App-Tools-API Referenz

Für: Entwickler und technische Projektpartner 10 Minuten Zuletzt geprüft: 07.10.2026

Die App-Tools-API hat einen zentralen Endpunkt. GET liefert den berechtigungsgefilterten Katalog, POST führt genau ein darin beschriebenes Tool aus. KI-Assistenten erreichen dieselben Tools über MCP: MCP und KI-Assistenten im Überblick.

Basis und Authentifizierung

  • Basis-URL: die HTTPS-Adresse deiner SynCore-Instanz
  • Endpunkt: /api/app-tools
  • Authentifizierung: Header X-API-KEY
  • Content-Type bei POST: application/json

GET /api/app-tools

Liefert alle für den Actor-User sichtbaren Tools.

Query-Parameter

ParameterTypStandardBedeutung
includeStructureBooleanfalseBei 1, true oder yes zusätzlich App-Struktur, effektive Rechte und Laufzeitregeln liefern.
stufeTextkeinename, beschreibung, schema oder typescript, siehe Katalog in Stufen. Ohne Angabe kommt die volle Form wie bisher.
appTextalleNur Tools dieser Apps, mehrere durch Komma getrennt, zum Beispiel crm,projektsyn.
sucheTextkeineSuchbegriffe durch Leerzeichen getrennt. Jeder Begriff muss in Name, App-Bezeichnung oder Beschreibung vorkommen.

Empfohlener Aufruf:

GET /api/app-tools?includeStructure=1 HTTP/1.1
Host: syncore.example.com
X-API-KEY: syn_...
Accept: application/json

Katalog in Stufen

Bei vollen Rechten liefert der Katalog über 1.000 Tools, rund 700 KB. Für das Finden reicht meist weniger:

StufeInhalt je ToolGröße des vollen Katalogs
namename, module, sideEffectrund 80 KB
beschreibungdazu appId, label, description, confirmationRequired, dataClassesrund 270 KB
schemaalle Felder aus Tool-Metadatenrund 700 KB
typescriptdie Tools als TypeScript-Deklaration, Antwort als Text statt JSONrund 550 KB

Mit Stufe enthält die Antwort zusätzlich stufe und anzahl. Sinnvoll ist ein Ablauf in zwei Schritten: erst ?stufe=name&suche=konto zum Finden, dann ?stufe=schema&suche=crm.konto.list für die Eingaben.

?stufe=typescript&app=crm liefert die Tools der App als Deklaration, die ein Programm oder ein KI-Agent direkt verwenden kann:

declare const syncore: {
  crm: {
    /** Liste/Suche: Konten (CRM) … */
    konto_list(input: CrmKontoListInput): Promise<SynCoreErgebnis<unknown>>;
  };
};

Die Typen beschreiben nur die Eingaben. Geprüft wird bei jedem POST weiter im Server: Schema, Rechte und Datenbereich.

Jede Antwort trägt einen ETag. Schickst du ihn beim nächsten Abruf im Header If-None-Match mit und hat sich nichts geändert, antwortet SynCore mit 304 ohne Inhalt. Eine unbekannte Stufe oder eine ungültige App-Kennung beantwortet SynCore mit 400.

Tool-Metadaten

FeldBedeutung
nameStabiler Name, der bei POST unverändert verwendet wird.
module / appIdZugehörige SynCore-App und stabile App-ID.
label / descriptionAnzeigename und fachliche Beschreibung.
inputSchemaZulässige Eingabe als JSON-Schema.
outputSchemaBeschreibung der Ausgabe, sofern für das Tool hinterlegt.
requiresErforderliche fachliche Berechtigungen.
dataClassesBetroffene Datenklassen. Tools für besonders geschützte Klasse-D-Daten werden nicht über diese Fläche angeboten.
sideEffectKennzeichnet, ob das Tool Daten liest oder einen Seiteneffekt auslöst.
confirmationRequiredEine aufrufende Anwendung muss vor der Ausführung eine ausdrückliche Bestätigung einholen.
dsgvoNoteDatenschutzhinweis zum Umfang der verarbeiteten oder übertragenen Daten.
Der Katalog ist die Vertragsgrundlage

Verwende keine fest eingebaute globale Tool-Liste. Apps, Rechte, Datenscopes und Tool-Schemas können sich je Mandant und Version unterscheiden. Maßgeblich ist immer die aktuelle GET-Antwort der Zielinstanz.

Hat dein Mandant externe Dienste angebunden, können deren Tools ebenfalls im Katalog stehen. dsgvoNote nennt dann, welche Daten an den Dienst gehen.

Alle Tools, die SynCore mitbringt, stehen mit Eingabefeldern und nötigen Rechten in der Referenz nach App. Welche davon du tatsächlich aufrufen darfst, zeigt dein Katalog.

POST /api/app-tools

Führt ein Tool im Kontext des Mandanten und des Actor-Users aus.

Request Body

{
  "name": "textbausteine.list_templates",
  "input": {
    "typ": "PDF",
    "limit": 20
  }
}
FeldPflichtBedeutung
namejaExakter Tool-Name aus dem aktuellen Katalog.
inputneinJSON-Objekt entsprechend inputSchema; ohne Eingabe {} verwenden.

Vor der Ausführung prüft SynCore den Tool-Namen, das Eingabeschema, die App-Aktivierung, alle benötigten Berechtigungen und den effektiven Datenscope.

Erfolgreiche Antwort

{
  "ok": true,
  "tool": "textbausteine.list_templates",
  "module": "textbausteine",
  "data": []
}

Je nach Tool können zusätzlich unter anderem summary, entityType, entityId, needsSelection oder candidates vorkommen. Beachte das gelieferte outputSchema und behandle unbekannte zusätzliche Felder tolerant.

Wenn needsSelection: true zurückkommt, darfst du nicht automatisch weiterschreiben. Zeige die Kandidaten an und lasse den Benutzer auswählen.

Listen blättern

Jedes lesende Listen-Tool nimmt limit und offset an. Liefert ein Tool höchstens 200 Einträge auf einmal (Standard und Höchstwert, bei den Datenobjekt-Listen …list Standard 50), steht in der Antwort zusätzlich seite:

{
  "ok": true,
  "tool": "textbausteine.list_documents",
  "data": [ … ],
  "seite": { "offset": 0, "limit": 200, "gesamt": 312, "weitere": true }
}

Bei weitere: true holst du die nächste Seite mit offset plus limit, hier "offset": 200. Ein limit über 200 beantwortet SynCore mit 400. Einige Listen-Tools liefern statt einer Liste ein kleines Objekt, etwa die Stufen einer Pipeline oder die Freigaben eines Datensatzes. Dort gibt es kein limit, das Eingabeschema im Katalog zeigt es.

Verbindlicher Ablauf bei Änderungen

  1. Katalog und Struktur abrufen.
  2. Zielentität über ein Lese- oder Such-Tool eindeutig bestimmen.
  3. Eingabe gegen inputSchema aufbauen.
  4. Bei confirmationRequired: true die konkrete Aktion bestätigen lassen.
  5. Mutation ausführen.
  6. Ergebnis mit einem Lese- oder Listen-Tool verifizieren.

Die Bestätigung ist eine Prozesspflicht der aufrufenden Anwendung. Es gibt dafür kein pauschales confirmed-Feld im Transportformat.

Dateien an einen Datensatz hängen

Mit files.upload legst du eine Datei an einem Datensatz ab, zum Beispiel ein Angebot an einem Projekt oder ein Foto an einer Aufgabe. files.list zeigt danach, was dort hängt.

{
  "name": "files.upload",
  "input": {
    "filename": "Angebot.pdf",
    "mimeType": "application/pdf",
    "contentBase64": "JVBERi0xLjcK...",
    "ownerType": "projektsyn.projekt",
    "ownerId": "prj_123"
  }
}
FeldPflichtBedeutung
filenamejaDateiname mit Endung, höchstens 255 Zeichen.
mimeTypejaDateityp, zum Beispiel application/pdf oder image/png. Er muss zum Inhalt passen.
contentBase64jaDateiinhalt als Base64, auch als data:-URL.
ownerTypejaArt des Datensatzes: projektsyn.projekt, projektsyn.ticket, crm.konto, crm.kontakt, crm.potenzial, vertraege.vertrag, auftraege.auftrag, produkte.artikel, seminar.katalog oder seminar.veranstaltung.
ownerIdjaID des Datensatzes aus dem passenden Lese-Tool.
tagsneinSchlagworte.
folderIdneinOrdner im Dateispeicher deines Mandanten.

Es gelten dieselben Regeln wie beim Hochladen im Browser:

  • Du brauchst das Recht, den Datensatz zu bearbeiten, und er muss in deinem Datenbereich liegen. Für files.list reicht das Leserecht.
  • Ein Datensatz, den es in deinem Mandanten nicht gibt oder den du nicht sehen darfst, ergibt 404.
  • Erlaubt sind PDF, Word, Excel, PowerPoint, Bilder (PNG, JPEG, GIF, WebP, HEIC), Text, CSV, JSON, XML und ZIP. SynCore prüft den Inhalt gegen den angegebenen Typ, HTML und SVG werden abgelehnt.
  • Eine vorhandene Datei wird nicht ersetzt, jeder Aufruf legt eine neue an.
  • Die größte Datei bestimmt deine Instanz (Standard 100 MB). Base64 macht die Anfrage etwa ein Drittel größer als die Datei, plane große Dateien entsprechend ein oder lade sie im Browser hoch.

Personal-, Bewerber-, Bildungs- und Belegakten nimmt das Tool bewusst nicht an. Lade Dokumente dort über die jeweilige Seite in SynCore hoch.

Base64 im Aufruf kostet Tokens: jedes Byte der Datei läuft durch das Sprachmodell, grob 400.000 Tokens je Megabyte. Von außen (MCP, API) nimmt files.upload deshalb nur kleine Dateien an (Standard 1 MB). Für alles, was als Datei vorliegt, gibt es den Link-Weg: das Werkzeug meldet die Datei an und liefert eine Adresse samt fertigem Befehl, die Bytes gehen direkt von der Platte zum Server.

  1. files.upload_link mit Name, Typ und Datensatz aufrufen. Die Antwort enthält url, expiresAt und befehle.bash beziehungsweise befehle.powershell.
  2. Den Befehl im Ordner der Datei ausführen, zum Beispiel:
curl -sS -f -T "foto.png" -H "Content-Type: image/png" "https://deine-instanz/api/files/direkt/<token>"
  1. Die Antwort des PUT ist die angelegte Datei (id, url). Mit files.list prüfen.

Für den Weg zurück liefert files.download_link mit der id aus files.list eine Adresse für GET, zum Beispiel curl -sS -f -o "foto.png" "<url>". Die Datei kommt als Anhang.

Regeln:

  • Ein Upload-Link gilt 15 Minuten und genau einmal, ein Download-Link 10 Minuten und bis dahin mehrfach.
  • Der Link ist an deinen Mandanten, deine Person, deinen API-Key und den Datensatz gebunden. Ein widerrufener Key macht den Link ungültig. Beim Abruf prüft SynCore das Recht am Datensatz noch einmal.
  • Der Content-Type im Befehl muss zum angemeldeten Typ passen, sonst antwortet der Server mit 415. Ohne Content-Type gilt der angemeldete Typ.
  • Beim Empfang gelten dieselben Prüfungen wie beim Hochladen im Browser (Typ-Allowlist, Inhalt, Größe, Virenscan). Wird die Datei abgelehnt, bleibt der Link bis zum Ablauf für einen korrigierten Versuch offen.
  • Je Person sind höchstens 20 offene Links gleichzeitig möglich.
  • Das Protokoll enthält Name, Typ und Größe, nie den Inhalt.

Der Befehl braucht eine Shell. Claude Code, Cursor und Skripte können ihn ausführen, ein Chat-Client ohne Shell nicht; dort bleibt files.upload für kleine Dateien.

HTTP-Statuscodes

StatusBedeutung
200Katalog geliefert oder Tool erfolgreich ausgeführt.
400Tool-Name fehlt, JSON ist ungültig oder input verletzt das Schema.
401Session beziehungsweise API-Key fehlt oder ist ungültig.
403Scope, Actor-User, App-Aktivierung oder fachliche Berechtigung fehlt.
404Der angegebene Tool-Name existiert nicht, oder das Tool findet den angegebenen Datensatz nicht.
413Die Datei ist größer, als die Instanz annimmt (files.upload, /api/files/direkt/<token>), oder der Base64-Aufruf von außen liegt über der kleinen Grenze (dann files.upload_link nehmen).
410Der Direktlink ist abgelaufen oder schon benutzt (/api/files/direkt/<token>).
415Der Content-Type des PUT passt nicht zum angemeldeten Typ (/api/files/direkt/<token>).
422Das Tool wurde gefunden, konnte die fachliche Aktion aber nicht ausführen.
429Zu viele Anfragen. Warte die Sekunden aus dem Header Retry-After ab.
501Für ein registriertes Tool fehlt serverseitig ein Handler; bitte den Support informieren.

Fehlerantworten

Bei 400, 401, 403, 404, 413 und 501 steht die Ursache im Feld message:

{
  "message": "Tool nicht gefunden: crm.konto_lsit"
}

Bei einem fachlichen Fehler liefert 422 stattdessen ok, tool und error:

{
  "ok": false,
  "tool": "beispiel.tool",
  "error": "Fachliche Ursache"
}

429 antwortet mit einem kurzen Klartext statt JSON und dem Header Retry-After. Welche Meldung was bedeutet, steht unter Wenn eine API-Anfrage scheitert.

Wiederhole 400, 403 oder 422 nicht blind. Korrigiere zuerst Eingabe, Rechte oder fachlichen Zustand.

Anfragelimits

SynCore zählt Anfragen mit API-Key je Schlüssel, Methode und Endpunkt in einem Zeitfenster von einer Minute.

LimitStandardwertFolge
Anfragen je API-Key1.200 pro Minute, getrennt für GET und POST429 Zu viele Anfragen bis zum Ende des Zeitfensters

Jede Antwort trägt X-RateLimit-Limit (Limit im Zeitfenster) und X-RateLimit-Remaining (verbleibende Anfragen). Bei 429 nennt Retry-After die Wartezeit in Sekunden. Die Werte sind Standardwerte und können je Instanz abweichen.

Sauber mit Limits umgehen

Verteile Massenläufe über die Zeit, wiederhole nach 429 erst nach Retry-After und nur einmal. Bei 401 prüfst du zuerst den Schlüssel, statt die Anfrage in einer Schleife zu wiederholen.

OpenAPI-Datei

Die Transport-API kannst du als OpenAPI 3.1 herunterladen und in Postman, Bruno oder Insomnia importieren. Da die verfügbaren Tools dynamisch sind, ersetzt die OpenAPI-Datei nicht den Katalogabruf.

Diese Seite als Klartext für KI-Assistenten: llms.txt