Dies ist eine maschinelle Übersetzung des englischen Originaldokuments. Im Falle von Widersprüchen zwischen dieser Übersetzung und der englischen Originalversion ist die englische Version maßgeblich. Englische Originalversion lesen
Öffentliche API
Caiioo enthält eine REST-API, mit der Sie alles programmatisch steuern können: Agenten ausführen, Tools verwalten, Aufgaben planen und mehr. Die API läuft auf demselben lokalen Server, der auch die Desktop-App und die Browser-Bridge antreibt.
Basis-URL: http://localhost:3847/v1
Authentifizierung: Zwei Wege zur Authentifizierung, beide über den API-Schalter in den Einstellungen gesteuert:
Für externe Konsumenten (Skripte, Integrationen, curl): Legen Sie ein API-Zugriffstoken in Einstellungen > API-Zugriff fest und verwenden Sie es als Bearer-Token:
curl -H \"Authorization: Bearer IHR_API_TOKEN\" http://localhost:3847/v1/providers
Für die lokale App (automatisch):
Die Caiioo Desktop-App, Browser-Erweiterungen und mobilen Apps authentifizieren sich automatisch über den vorhandenen Relay-Auth-Header (x-relay-auth; HTTP-Header sind Case-Insensitive). Keine manuelle Einrichtung erforderlich – die App erledigt dies im Hintergrund. Relay-Auth-Anfragen umgehen den Schalter „Öffentliche API aktivieren“, da sie bereits vertrauenswürdig sind; nur Bearer-Token-Anfragen werden durch den Schalter gesteuert.
Einrichtung:
- Öffnen Sie Caiioo Einstellungen > API-Zugriff
- Schalten Sie Öffentliche API aktivieren ein
- Legen Sie ein API-Zugriffstoken fest (eine beliebige Zeichenfolge – behandeln Sie sie wie ein Passwort)
- Verwenden Sie dieses Token in allen API-Anfragen
Die API ist auf localhost und über das private Relay verfügbar. Überprüfen Sie GET /v1/auth/info (keine Authentifizierung erforderlich) für den aktuellen Status und Einrichtungsanweisungen.
Ratelimits: Jede /v1/* Anfrage ist pro Client-IP limitiert – 100 GET-Anfragen pro Minute für Lesezugriffe und insgesamt 30 Schreib-Anfragen pro Minute (POST / PATCH / DELETE). Anfragen über dem Limit erhalten einen 429-Fehler. Webhook-Zustellungen (POST /v1/webhooks/:id) sind nicht Bearer-authentifiziert und unterliegen nicht diesen Limits.
Profile
Ein einzelnes Gerät kann mehrere Benutzerprofile enthalten (z. B. Privat + Arbeit). Die API ermöglicht es externen Skripten, die verfügbaren Profile zu prüfen und das aktive Profil zu wechseln, bevor andere Aufgaben ausgeführt werden. Das Erstellen, Aktualisieren und Löschen von Profilen wird bewusst nicht über die öffentliche API angeboten — diese Abläufe gehören in die Onboarding-Benutzeroberfläche der App.
Profile auflisten:
GET /v1/profiles
Gibt { profiles: [...] } mit einem Eintrag pro nicht gelöschtem Profil zurück. Jeder Eintrag enthält id, name, email, avatarUrl, tier, accessibleModes, license, organization, preferences, onboardingComplete, createdAt, lastAccessedAt. Token-haltige Felder (serviceCredentials, oauthConnections) und Synchronisations-Interna (vectorClock, lastModifiedBy) werden entfernt. Verwenden Sie /v1/connectors, um OAuth-Verbindungen zu prüfen.
Aktives Profil abrufen:
GET /v1/profiles/active
Gibt { profile } für das aktuell von diesem Server verwendete Profil zurück. Alle /v1/*-Ressourcen, die auf ein Profil bezogen sind (Threads, Anhänge, Einstellungen, Skills), beziehen sich auf dieses Profil.
Aktives Profil wechseln:
PUT /v1/profiles/active
Content-Type: application/json
{ "profileId": "user-uuid-aus-der-liste" }
Gibt { profile } für das neu aktivierte Profil zurück. Gibt 404 zurück, wenn die ID kein bekanntes Profil ist.
Providers & Models
Entdecken Sie, welche LLM-Provider konfiguriert sind und welche Modelle zur Verfügung stehen.
Provider auflisten:
GET /v1/providers
Gibt jeden unterstützten Provider-Typ zurück. Derzeit: anthropic, openai, google, openrouter, ollama, poe, mlx, perplexity, baseten, cloudflare. Jeder Eintrag enthält type, displayName, icon, requiresApiKey, hasApiKey sowie ein capabilities-Objekt mit den unten aufgeführten Flags.
| Capability-Flag | Bedeutung |
|---|---|
supportsVision |
Provider kann Bild-Inputs verarbeiten |
supportsPdfFile |
Provider kann native PDF-Datei-Content-Blöcke akzeptieren |
supportsToolCalling |
Provider unterstützt Funktions-/Tool-Aufrufe |
supportsStreaming |
Provider überträgt Tokens inkrementell per Streaming |
supportsExtendedThinking |
Provider bietet ein Budget für Reasoning/Thinking an |
supportsPromptCaching |
Provider unterstützt Prompt-Caching-Direktiven |
nativeReasoningBlocks |
Provider gibt Denkprozesse als native Nachrichtenblöcke aus (statt als Text) |
requiresThoughtSignature |
Provider erfordert, dass signierte Thought-Tokens zurückgesendet werden |
Die Capability-Flags spiegeln das Feld readonly capabilities der jeweiligen Provider-Klasse wider (siehe src/shared/providers/*-provider.ts) und werden durch einen Drift-Sentinel-Test validiert — rufen Sie diesen Endpunkt zur Laufzeit auf, anstatt die Matrix fest im Code zu hinterlegen.
Hinweise für BYOK-Provider:
perplexitystellt eine kuratierte Liste von Sonar-Modellen bereit (Perplexity verfügt über keinen öffentlichen/models-Endpunkt).cloudflare(AI Gateway) ist BYOK + Multi-Vendor; die Modellliste wird durch Ihre Gateway-Konfiguration bestimmt und von/v1/providers/cloudflare/modelsals leeres Array zurückgegeben. Verwenden Sie Ihren eigenen Gateway-Katalog.
Modelle eines Providers auflisten:
GET /v1/providers/openrouter/models
Gibt den Modellkatalog für diesen Provider zurück. Jedes Modell enthält id, displayName und, sofern verfügbar, contextLength. Gibt 503 zurück, wenn dem Provider ein API-Key fehlt oder sein Upstream-Katalog nicht erreichbar ist.
Gesamtkatalog über alle Provider hinweg:
GET /v1/models
Führt die Modelle aller konfigurierten Provider in einer Liste zusammen. Provider ohne API-Keys werden übersprungen und unter warnings aufgeführt.
Agenten
Agenten sind das Herzstück von caiioo. Jeder Agent ist ein Modus — eine konfigurierte Persönlichkeit mit eigenem System-Prompt, Tools, Variablen und Skills.
Alle Agenten auflisten:
GET /v1/agents
Gibt integrierte Agenten (Shopping, Arbeitsplatz, Allgemein) und alle von Ihnen erstellten benutzerdefinierten Agenten zurück. Jeder ist mit source: \"builtin\" oder source: \"custom\" markiert.
Einen benutzerdefinierten Agenten erstellen:
POST /v1/agents
Content-Type: application/json
{
\"id\": \"mein-forschungs-agent\",
\"branding\": {
\"name\": \"Forschungs-Agent\",
\"description\": \"Durchsucht das Web und fasst Ergebnisse zusammen\"
},
\"defaultSettings\": {
\"systemPrompt\": \"Du bist ein Forschungsassistent. Zitiere immer Quellen.\",
\"enabledTools\": { \"web_browsing\": true, \"search_tools\": true }
},
\"settingLevels\": {}
}
Gibt 201 mit dem erstellten Agenten zurück. Eine Vector Clock wird für die Synchronisierung automatisch angehängt.
Einen Agenten aktualisieren:
PATCH /v1/agents/mein-forschungs-agent
Content-Type: application/json
{ \"branding\": { \"name\": \"Forschungs-Agent\", \"description\": \"Aktualisierte Beschreibung\" } }
Führt den Patch in den bestehenden Agenten zusammen und erhöht die Vector Clock. Integrierte Agenten geben 403 zurück — sie sind schreibgeschützt.
Einen Agenten löschen:
DELETE /v1/agents/mein-forschungs-agent
Führt einen Soft-Delete via Tombstone durch (synchronisiert über Geräte). Gibt 204 zurück.
Ausführen von Agenten
Dies ist das Hauptereignis — rufen Sie einen Agenten auf, um eine Nachricht zu verarbeiten.
Request body — unterstützte Felder
| Feld | Erforderlich | Beschreibung |
|---|---|---|
agentId |
ja | ID des integrierten Modus (z. B. general) oder eine benutzerdefinierte Agent-ID |
input.message |
ja | Text der Benutzernachricht |
input.attachments |
nein | Array von Attachment-IDs (bereits über /v1/attachments hochgeladen), die diesem Turn beigefügt werden sollen |
input.variables |
nein | Variablen-Overrides pro Durchlauf, die in den Variablen-Resolver des Agenten eingefügt werden |
input.tabContext |
nein | Freiform-String, der als Seitenkontext injiziert wird (verwendet von der Browser-Bridge) |
input.messageId |
nein | Vom Client bereitgestellte Nachrichten-ID — nützlich für die Deduplizierung bei Wiederholungsversuchen |
threadId |
nein | Bestehender Thread, der fortgesetzt werden soll. Falls weggelassen, wird ein neuer Thread erstellt und zurückgegeben |
mode |
nein | "sync" oder "async". Standardwert ist "async" |
Synchroner Modus
Warten Sie auf die vollständige Antwort:
POST /v1/runs
Content-Type: application/json
{
"agentId": "general",
"input": { "message": "Wie ist das Wetter heute in Paris?" },
"mode": "sync"
}
Gibt 200 mit { content, usage, status: "completed" } zurück, nachdem der Agent fertig ist. Wenn der Agent einen Fehler verursacht, wird 500 mit { error, status: "error" } zurückgegeben. Synchrone Durchläufe werden nach 5 Minuten mit status: "error" abgebrochen, wenn kein terminales Ereignis empfangen wird — verwenden Sie async + SSE für alles, was länger dauern könnte.
Asynchroner Modus
Fire-and-Forget — nützlich für lang laufende Aufgaben:
POST /v1/runs
Content-Type: application/json
{
"agentId": "my-research-agent",
"input": { "message": "Schreibe eine 2000 Wörter umfassende Analyse der Trends bei erneuerbaren Energien" },
"mode": "async"
}
Gibt sofort 202 mit { runId, threadId, status: "running" } zurück.
Status abfragen (Polling):
GET /v1/runs/{runId}
Gibt { run: { runId, threadId, agentId, status, createdAt, content?, usage?, error? } } zurück. Der Status ist einer von running, completed, error oder cancelled.
Ereignisse in Echtzeit streamen (SSE):
GET /v1/runs/{runId}/events
Gibt einen text/event-stream mit jedem Agenten-Ereignis zurück, sobald es eintritt: GENERATION_STARTED, STREAMING_CONTENT, Tool-Aufrufe, Subagent-Aktivitäten und das terminale Ereignis (GENERATION_COMPLETE, GENERATION_ERROR oder GENERATION_CANCELLED).
Nach dem terminalen Ereignis sendet der Server einen letzten SSE-Frame mit event: terminal und einem leeren Daten-Payload als explizites Ende-des-Streams-Signal und schließt dann die Verbindung. Clients sollten den Empfang dieses Frames (oder das Schließen der Verbindung) als Signal zum Beenden des Lesevorgangs behandeln.
Wenn Sie sich anmelden, nachdem der Durchlauf bereits beendet ist, spielt der Server einen Frame vom Typ RUN_SNAPSHOT ab, der den vollständigen finalen record enthält, gefolgt vom event: terminal Signal, und schließt dann die Verbindung.
Einen Durchlauf abbrechen:
POST /v1/runs/{runId}/cancel
Gibt { run: { ..., status: "cancelled" } } zurück.
Threads
Threads sind Konversationen. Jeder Agent-Durchlauf findet innerhalb eines Threads statt, und Threads bleiben über Sitzungen hinweg bestehen. Die API ermöglicht es Ihnen, Threads programmatisch aufzulisten, zu lesen, zu erstellen und zu verwalten.
Alle Threads auflisten (nur Metadaten):
GET /v1/threads
Gibt { threads: [...] } für das aktuelle Profil zurück, wobei messages entfernt wurden (verwenden Sie den Detail-Endpunkt, wenn Sie diese benötigen). Jedes andere Feld bleibt erhalten — id, title, createdAt, updatedAt, modeId, archived, Nutzungsstatistiken, plus subAgentHistories, anonymizerSnapshot, threadToolApprovals, threadVariables, threadToolOverrides, messagingBinding, scheduledTaskId, sofern gesetzt. (Die umfangreichere Payload ist exklusiv für die API — der WebSocket-Sidebar-Broadcast verwendet eine stärkere Reduzierung, um unter den Übertragungslimits zu bleiben.)
Einen Thread mit vollständigen Nachrichten abrufen:
GET /v1/threads/{id}
Gibt den vollständigen Thread einschließlich seines messages-Arrays zurück — jede Benutzernachricht, Assistant-Antwort, jeder Tool-Aufruf und jedes Tool-Ergebnis.
Nur die Nachrichten abrufen:
GET /v1/threads/{id}/messages
Gibt nur das messages-Array zurück — schlanker als das vollständige Thread-Objekt, wenn Sie nur die Konversation benötigen.
Einen Thread erstellen:
POST /v1/threads
Content-Type: application/json
{ "title": "Research project", "modeId": "general" }
Gibt 201 mit { thread } zurück. Der neue Thread erscheint sofort in der Sidebar (via WebSocket-Broadcast). Die API wechselt beim Erstellen niemals den aktiven Thread der App — rufen Sie separat PUT /v1/threads/active auf, falls dies gewünscht ist.
Einen Thread aktualisieren:
PATCH /v1/threads/{id}
Content-Type: application/json
{ "title": "Renamed project", "archived": true }
Aktualisierbare Felder: title, modeId, archived, lastUsedModel. Änderungen werden in Echtzeit an die Sidebar übertragen.
Einen Thread löschen:
DELETE /v1/threads/{id}
Führt ein Soft-Delete des Threads aus (Tombstone für die Synchronisation). Gibt 204 zurück. Gelöschte Threads werden in den Papierkorb verschoben und können wiederhergestellt werden, bis der Papierkorb geleert wird.
Aktiver Thread:
GET /v1/threads/active # Gibt { threadId } zurück
PUT /v1/threads/active # Body: { "threadId": "..." }
Papierkorb-Verwaltung:
GET /v1/threads/trash/count # Gibt { count } zurück
POST /v1/threads/trash/empty # Gibt { deletedCount, protectedCount } zurück
Geschützte Threads (die über die Datenrückhalte-Option beibehalten werden) sind vom Leeren des Papierkorbs ausgeschlossen.
Fortsetzen einer Konversation über die API:
Um eine Folgenachricht an einen bestehenden Thread zu senden, verwenden Sie POST /v1/runs mit der ID des Threads:
POST /v1/runs
Content-Type: application/json
{
"agentId": "general",
"threadId": "existing-thread-id",
"input": { "message": "Follow up on that last point" },
"mode": "sync"
}
Der Agent sieht den vollständigen Konversationsverlauf aus dem Thread.
Anhänge
Anhänge sind Dateien, die mit Threads verknüpft sind – Screenshots, PDFs, Dokumente, hochgeladene Bilder, generierte Artefakte. Die API ermöglicht es Ihnen, diese aufzulisten, hochzuladen, herunterzuladen und zu verwalten.
Alle Anhänge auflisten (nur Metadaten):
GET /v1/attachments
Gibt Anhang-Metadaten für das aktuelle Profil zurück. Umfangreiche Felder (dataUrl, extractedContent, extractedImages) werden entfernt – verwenden Sie dafür die Detail- oder Inhalts-Endpunkte.
Anhänge für einen bestimmten Thread auflisten:
GET /v1/threads/{threadId}/attachments
Anhang-Metadaten abrufen:
GET /v1/attachments/{id}
Gibt vollständige Metadaten zurück, einschließlich extractedContent (OCR-Text, geparstes Markdown), contentType, fileName, size und ein hasContent-Flag. Die rohe Binärdatei ist NICHT enthalten – verwenden Sie dafür den /content-Endpunkt.
Binärdatei eines Anhangs herunterladen:
GET /v1/attachments/{id}/content
Gibt die Rohdatei mit den korrekten Headern für Content-Type und Content-Disposition zurück. Leiten Sie dies in eine Datei um:
curl -o ausgabe.pdf \
-H "Authorization: Bearer $API_TOKEN" \
http://localhost:3847/v1/attachments/{id}/content
Einen Anhang hochladen:
POST /v1/attachments
Content-Type: application/json
{
"threadId": "thread-id",
"type": "user_upload",
"contentType": "application/pdf",
"fileName": "bericht.pdf",
"description": "Quartalsbericht",
"dataUrl": "data:application/pdf;base64,JVBERi0xLjQ..."
}
Die dataUrl ist eine base64-kodierte Daten-URL. Gibt 201 mit der neuen Anhang-ID zurück. Der Anhang wird mit dem angegebenen Thread verknüpft.
Anhang-Metadaten aktualisieren:
PATCH /v1/attachments/{id}
Content-Type: application/json
{ "description": "Aktualisierte Beschreibung", "fileName": "neuer-name.pdf" }
Einen Anhang löschen:
DELETE /v1/attachments/{id}
Soft-Delete via Tombstone. Gibt 204 zurück.
MCP-Server
Verwalten Sie Ihre MCP (Model Context Protocol) Server-Verbindungen — die Server, die Agenten Zugriff auf externe Tools und Datenquellen ermöglichen.
Konfigurierte Server auflisten:
GET /v1/mcp-servers
Gibt alle MCP-Server-Konfigurationen für das aktuelle Profil zurück. Sensible Felder (authToken, env, credentialId) werden aus der Antwort entfernt.
Konfiguration eines Servers abrufen:
GET /v1/mcp-servers/{id}
Einen neuen MCP-Server hinzufügen:
POST /v1/mcp-servers
Content-Type: application/json
{
"id": "my-server",
"name": "My MCP Server",
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-filesystem", "/path/to/files"],
"serverType": "local"
}
Verwenden Sie für Remote-HTTP-Server "url" anstelle von "command":
{
"id": "remote-server",
"name": "Remote API",
"url": "https://my-mcp-server.example.com/sse",
"serverType": "remote"
}
Akzeptierte optionale Felder bei POST: command, args, env, url, description, transportType, authType, authToken, authHeader, headers, specType, specPath, timeoutMs, credentialId, oauthConnectionId, approval. Vom Server verwaltete Felder (customOAuth, hubPackageId, profileId, connectorId, teamPublished, teamOrgId, vectorClock, ...) können nicht über die API gesetzt werden.
Einen Server aktualisieren:
PATCH /v1/mcp-servers/{id}
Content-Type: application/json
{ "name": "Renamed Server", "args": ["-y", "@mcp/server-v2"] }
Die über Patch änderbaren Felder entsprechen der POST-Allowlist (einschließlich credentialId und oauthConnectionId — praktisch für die Rotation einer OAuth-Verbindung ohne Löschen und Neuerstellen). Vom Server verwaltete Felder bleiben schreibgeschützt.
Einen Server aktivieren/deaktivieren:
POST /v1/mcp-servers/{id}/toggle
Content-Type: application/json
{ "enabled": false }
}
Einen Server löschen:
DELETE /v1/mcp-servers/{id}
Prozessverwaltung
Für lokale (stdio) MCP-Server können Sie den Serverprozess direkt verwalten.
Laufende Prozesse auflisten:
GET /v1/mcp-servers/processes
Gibt laufende Serverprozesse mit pid, startedAt und dem Status running zurück.
Einen Server starten:
POST /v1/mcp-servers/{id}/start
Liest command/args/env aus der Serverkonfiguration und startet den Prozess. Gibt den Prozessstatus zurück.
Einen Server stoppen:
POST /v1/mcp-servers/{id}/stop
Beendet den Serverprozess ordnungsgemäß (SIGTERM mit Fallback auf SIGKILL).
Eine JSON-RPC-Methode direkt aufrufen:
POST /v1/mcp-servers/{id}/call
Content-Type: application/json
{ "method": "tools/list", "params": {} }
Sendet eine rohe JSON-RPC 2.0-Anfrage an den Server und gibt das Ergebnis zurück. Nützlich für das Debugging oder den Aufruf von Methoden, die nicht über die Tools-API bereitgestellt werden.
Tools & Toolkits
Durchsuchen und rufen Sie die Tools auf, die Agenten verwenden — Web-Browsing, Suche, Kalender, Gmail, Slate und mehr.
Toolkits auflisten (gruppiert):
GET /v1/toolkits
Gibt eingebettete Tools gruppiert nach Kategorie (Produktivität, Suche, Dienstprogramme usw.) und alle verbundenen MCP-Server als separate Toolkits zurück, jeweils mit ihren aufgelisteten Aktionen.
Alle Tools auflisten (flach):
GET /v1/tools
GET /v1/tools?source=embedded # Nur integrierte Tools
GET /v1/tools?source=mcp # Nur MCP-Server-Tools
Tool-Details mit Eingabeschema abrufen:
GET /v1/tools/calculator
Gibt { tool: { name, displayName, description, source, category, inputSchema, actions?, requiredTier?, requiredRuntimes?, riskTier?, riskExplanation?, requiresApproval? } } zurück.
| Feld | Bedeutung |
|---|---|
inputSchema |
JSON-Schema für die Eingabe des Tools — vor dem Aufruf validieren |
actions |
Optionale Unteraktionen (z. B. Slate read/write); jede hat id, displayName, description, optional requiredTier |
requiredTier |
Mindest-User-Tier (free, falls weggelassen). Public-API-Aufrufe lehnen alles über free ab |
requiredRuntimes |
Plattformen, auf denen dieses Tool verfügbar ist (macos, ios, etc.); weglassen ⇒ überall |
riskTier |
Zustimmungsrisiko: low (Standard), medium, high |
riskExplanation |
Menschlich lesbarer Grund, warum riskTier erhöht ist |
requiresApproval |
true, wenn das Tool pro Aufruf eine Benutzerzustimmung benötigt — Public-API-Aufrufe lehnen diese ab |
Ein Tool direkt aufrufen:
POST /v1/tools/calculator/invoke
Content-Type: application/json
{ "input": { "expression": "sqrt(144) + 3^2" }, "threadId": "optional-thread-id" }
Gibt { result } zurück. Die Eingabe wird gegen das Schema des Tools validiert — ungültige Eingaben geben 422 mit Details zurück. Übergeben Sie eine optionale threadId, wenn das Tool einen Thread-bezogenen Kontext benötigt (z. B. Attachment-Lookups).
Gating — was die öffentliche API ablehnt:
- Tier-beschränkte Tools (
metadata.requiredTier !== 'free') →403. Der Agent-Loop prüft das Tier gegen die Sitzung des Benutzers; die öffentliche API hat keinen übertragenen Tier-Kontext, daher ist die konservative Richtlinie die Ablehnung. Verwenden Sie stattdessenPOST /v1/runsmit einem Agenten, der über das richtige Tier verfügt. - Zustimmungspflichtige Tools (
metadata.approval.requiresApproval === true) →403. Es gibt keinen Menschen im Prozess, der gefragt werden könnte. Rufen Sie diese überPOST /v1/runsauf (was dem Benutzer die Abfrage anzeigt) oder stellen Sie den Tool-Zustimmungsmodus in der App aufapprove_allein, um dies zu umgehen. - Remote MCP-Tools →
501mit dem Hinweis,/v1/runszu verwenden (diese erfordern den Transport über den Agent-Subprozess).
Vision- und bildbasierte Tools: Laden Sie diese zuerst über POST /v1/attachments hoch und übergeben Sie dann die zurückgegebene Attachment-ID innerhalb von input (z. B. { "input": { "attachment_id": "att_abc", "prompt": "Was ist auf diesem Bild zu sehen?" } }). Das Tool liest die Binärdaten über die threadId aus dem Speicher; Sie übergeben die Bytes nicht direkt im Aufruf.
Connectors
Verwalten Sie OAuth-Integrationen – Google, Microsoft, GitHub, Notion, Slack und mehr.
Verfügbare Integrationen durchsuchen:
GET /v1/connectors/catalog
Gibt alle registrierten OAuth-Anbieter mit Namen, Kategorie und Standard-Scopes zurück.
Ihre verbundenen Konten auflisten:
GET /v1/connectors
Gibt aktive Verbindungen für das aktuelle Profil zurück. Token werden niemals offengelegt – nur Metadaten (Anbieter, E-Mail, Status, Scopes, Zeitstempel).
Einzelne Verbindung abrufen:
GET /v1/connectors/{id}
Gibt Metadaten für eine Verbindung zurück. Token werden niemals offengelegt.
Verbindungsstatus prüfen:
POST /v1/connectors/{id}/test
Gibt { health: { status, isTokenExpired, canRefresh } } zurück.
Verbindung entfernen:
DELETE /v1/connectors/{id}
Das Erstellen neuer Verbindungen erfordert den interaktiven OAuth-Flow über die App-UI oder die /auth/* Routen.
Trigger
Planen Sie Agenten für die automatische Ausführung – tägliche Briefings, wöchentliche Berichte, intervallbasierte Überwachung.
Jeder Trigger hat einen kind-Diskriminator: schedule (Standard – zeitgesteuert), webhook (wird ausgelöst, wenn ein externer Dienst an den Webhook-Pfad sendet) oder messaging (wird von einem verbundenen Messaging-Adapter ausgelöst – z. B. eingehende Slack/Discord-Nachrichten, die einem Kanalfilter entsprechen).
Trigger auflisten:
GET /v1/triggers
Gibt { triggers: [...] } zurück. Jeder Eintrag enthält seinen Typ (kind), Zeitplan und typspezifische Felder (z. B. webhookSecret/webhookPath für Webhook-Trigger).
Einzelnen Trigger abrufen:
GET /v1/triggers/{id}
Geplanten Trigger erstellen:
POST /v1/triggers
Content-Type: application/json
{
\"name\": \"Morgen-Briefing\",
\"prompt\": \"Fasse meine ungelesenen E-Mails und den heutigen Kalender zusammen\",
\"modeId\": \"general\",
\"schedule\": { \"type\": \"daily\", \"time\": \"08:00\" }
}
Unterstützte Zeitplantypen:
{ \"type\": \"interval\", \"minutes\": 60 }– alle N Minuten (min 15, max 1440){ \"type\": \"daily\", \"time\": \"09:00\" }– täglich zu einer bestimmten Zeit{ \"type\": \"weekly\", \"day\": \"mon\", \"time\": \"09:00\" }– wöchentlich{ \"type\": \"weekdays\", \"time\": \"08:30\" }– Montag bis Freitag{ \"type\": \"daysOfWeek\", \"days\": [\"mon\", \"wed\", \"fri\"], \"time\": \"10:00\" }– spezifische Tage{ \"type\": \"monthly\", \"dayOfMonth\": 1, \"time\": \"09:00\" }– monatlich{ \"type\": \"manual\" }– nur bei manuellem Aufruf via API
Trigger manuell auslösen:
POST /v1/triggers/{id}/fire
Gibt 202 mit einer threadId für den resultierenden Lauf zurück.
Aktualisieren oder Löschen:
PATCH /v1/triggers/{id}
DELETE /v1/triggers/{id}
Webhooks
Webhook-Trigger ermöglichen es externen Diensten (CI/CD, Monitoring, Formular-Builder), einen Agentenlauf via HTTP auszulösen.
Webhook-Trigger erstellen:
POST /v1/triggers
Content-Type: application/json
{
\"name\": \"Deploy-Hook\",
\"prompt\": \"Ein Deployment ist erfolgt: {{webhook.body}}\",
\"modeId\": \"general\",
\"kind\": \"webhook\"
}
Gibt 201 mit einem webhookSecret und webhookPath zurück. Speichern Sie das Secret – Sie benötigen es zum Signieren der Payloads.
Webhook senden:
# HMAC-SHA256 des rohen Request-Bodys berechnen
SIGNATURE=$(echo -n '{\"repo\":\"my-app\",\"branch\":\"main\"}' | openssl dgst -sha256 -hmac \"$WEBHOOK_SECRET\" | awk '{print $2}')
POST /v1/webhooks/{triggerId}
Content-Type: application/json
X-Webhook-Signature: $SIGNATURE
{\"repo\": \"my-app\", \"branch\": \"main\"}
Der Webhook-Endpunkt erfordert KEINE Bearer-Authentifizierung – er verwendet stattdessen die HMAC-Verifizierung. Gibt 202 mit der threadId des gestarteten Laufs zurück. Der Platzhalter {{webhook.body}} im Trigger-Prompt wird durch den rohen Request-Body ersetzt.
Messaging-Trigger
Messaging-Trigger werden ausgelöst, wenn ein verbundener Messaging-Adapter (z. B. eine über den Community Hub installierte Slack- oder Discord-Integration) eine eingehende Nachricht empfängt, die dem Filter des Triggers entspricht. Erstellung mit kind: \"messaging\":
POST /v1/triggers
Content-Type: application/json
{
\"name\": \"Erwähnungs-Beantworter\",
\"prompt\": \"Antworte hilfreich auf: {{message.text}}\",
\"modeId\": \"general\",
\"kind\": \"messaging\",
\"messagingAdapterId\": \"slack-team-acme\",
\"messagingChannelFilter\": \"#support\"
}
Der Adapter ist dafür verantwortlich, passende Ereignisse an den Trigger weiterzuleiten; messagingChannelFilter ist adapterspezifisch.
Benutzerdefinierte Funktionen
Erstellen Sie Ihre eigenen Tools, die Agenten aufrufen können. Funktionen werden in JavaScript oder Python geschrieben und in einer Sandbox ausgeführt.
Funktionen auflisten:
GET /v1/functions
Eine Funktion erstellen:
POST /v1/functions
Content-Type: application/json
{
"name": "calculate_bmi",
"description": "Berechne den Body-Mass-Index aus Größe und Gewicht",
"language": "javascript",
"source": "return { bmi: (input.weightKg / (input.heightM * input.heightM)).toFixed(1) };",
"inputSchema": {
"type": "object",
"properties": {
"weightKg": { "type": "number" },
"heightM": { "type": "number" }
},
"required": ["weightKg", "heightM"]
}
}
JavaScript-Funktionen erhalten input und müssen ein Ergebnis zurückgeben. Python-Funktionen setzen eine result-Variable:
# Python-Beispiel
result = {"bmi": round(input["weightKg"] / (input["heightM"] ** 2), 1)}
Eine Funktion direkt ausführen:
POST /v1/functions/{id}/execute
Content-Type: application/json
{ "input": { "weightKg": 75, "heightM": 1.80 } }
Sicherheit: JavaScript läuft in der vm-Sandbox von Node (kein Dateisystem- oder Netzwerkzugriff, 10s Timeout). Python läuft als Subprozess mit einem 30s Timeout. Beide validieren die Eingabe vor der Ausführung.
Aktualisieren oder löschen:
PATCH /v1/functions/{id}
DELETE /v1/functions/{id}
Skills
Skills sind gespeicherte Prompts, auf die Agenten verweisen können und die aus der Ansicht für leere Konversationen schnell gestartet werden können. Über den Hub installierte Skills (verwaltet via Paketinstallation) sind hier NICHT enthalten — nur vom Benutzer erstellte Skills werden aufgelistet und sind bearbeitbar.
Skills auflisten:
GET /v1/skills
Gibt { skills: [...] } der vom Benutzer erstellten Skills für das aktive Profil zurück. Gelöschte (Tombstoned), Hub-Overlay- und Sync-Shadow-Skills werden herausgefiltert.
Einen Skill abrufen:
GET /v1/skills/{id}
Einen Skill erstellen:
POST /v1/skills
Content-Type: application/json
{
"prompt": "Fasse die Seite in 3 Stichpunkten zusammen.",
"tags": ["utility", "summarize"],
"isFavorite": true,
"modes": ["general"],
"displayName": "Schnellzusammenfassung",
"description": "Drei-Punkte-TL;DR der aktiven Seite"
}
Nur prompt ist erforderlich. modes (optional) beschränkt den Skill auf bestimmte Agenten-IDs; weglassen für alle Modi. Gibt 201 mit dem neuen Skill zurück (einschließlich serverzugewiesener id, createdAt, updatedAt).
Einen Skill aktualisieren:
PATCH /v1/skills/{id}
Content-Type: application/json
{ "prompt": "Aktualisierter Prompt", "isFavorite": false }
Anpassbare Felder: prompt, tags, modes, displayName, description, isFavorite. Versuche, einen Hub-Overlay-Skill zu ändern, geben 404 zurück.
Einen Skill löschen:
DELETE /v1/skills/{id}
Führt eine Soft-Löschung via Tombstone durch. Gibt 204 zurück. Hub-Overlay-Skills geben 404 zurück — deinstallieren Sie stattdessen das Quellpaket.
Workflows
Orchestrieren Sie mehrere Agenten in einem DAG (gerichteter azyklischer Graph) – führen Sie Schritte nach Möglichkeit parallel aus und leiten Sie Ausgaben früherer Schritte in spätere ein.
Einen Workflow-Graphen validieren:
POST /v1/workflows/validate
Content-Type: application/json
{
"graph": {
"nodes": [
{ "id": "research", "agentId": "general", "prompt": "Erforsche Trends bei erneuerbaren Energien" },
{ "id": "analyze", "agentId": "general", "prompt": "Recherchiere Wettbewerberpreise" },
{ "id": "report", "agentId": "general", "prompt": "Schreibe einen Bericht, der Folgendes kombiniert: {{outputs.research}} und {{outputs.analyze}}", "dependsOn": ["research", "analyze"] }
]
}
}
Gibt { valid: true/false, errors: [...] } zurück. Prüft auf Zyklen, doppelte IDs und fehlende Abhängigkeitsreferenzen.
Einen Workflow ausführen:
POST /v1/workflows/execute
Content-Type: application/json
{
"graph": {
"nodes": [
{ "id": "research", "agentId": "general", "prompt": "Erforsche Trends bei erneuerbaren Energien" },
{ "id": "summarize", "agentId": "general", "prompt": "Fasse zusammen: {{outputs.research}}", "dependsOn": ["research"] }
]
}
}
Gibt { status: "completed", outputs: { research: "...", summarize: "..." }, nodeResults: {...} } zurück.
Unabhängige Knoten (ohne gemeinsame Abhängigkeiten) laufen parallel. Der Platzhalter {{outputs.nodeId}} im Prompt eines Knotens wird durch den Inhalts-Output des genannten Upstream-Knotens ersetzt. Jeder Knoten ist ein vollständiger Agentenlauf, kann also Tools verwenden, im Web surfen und auf alle Funktionen des Zielagenten zugreifen.
Wissensdatenbanken
Organisieren Sie Dokumente in durchsuchbaren Sammlungen, auf die Agenten Bezug nehmen können.
Wissensdatenbanken auflisten:
GET /v1/knowledge/bases
Eine Wissensdatenbank erstellen:
POST /v1/knowledge/bases
Content-Type: application/json
{ "name": "Forschungsarbeiten" }
Gibt 201 mit der neuen Basis-ID zurück.
Ein Dokument in eine Wissensdatenbank hochladen:
POST /v1/knowledge/bases/{id}/documents
Content-Type: application/json
{
"fileName": "research-paper.pdf",
"contentType": "application/pdf",
"dataUrl": "data:application/pdf;base64,JVBERi0xLjQ...",
"description": "Trends bei erneuerbaren Energien 2026"
}
Das Feld dataUrl ist eine base64-kodierte Daten-URL. Gibt 201 mit den Dokument-Metadaten zurück.
Dokumente in einer Wissensdatenbank auflisten:
GET /v1/knowledge/bases/{id}/documents
In einer Wissensdatenbank suchen:
POST /v1/knowledge/bases/{id}/search
Content-Type: application/json
{ "query": "erneuerbare energien" }
Gibt passende Dokumente basierend auf Dateiname und Beschreibung zurück. Die semantische (Vektor-)Suche folgt in einer zukünftigen Version.
Ein Dokument oder eine Wissensdatenbank löschen:
DELETE /v1/knowledge/bases/{id}/documents/{docId}
DELETE /v1/knowledge/bases/{id}
Agenten exportieren & importieren
Teilen Sie Agenten als portable Pakete — über Geräte, Teams oder den Community Hub hinweg.
Einen Agenten exportieren:
POST /v1/agents/{id}/export
Gibt ein JSON-Paket zurück, das die Agentendefinition, Tool-Anforderungen (abgeleitet von aktivierten Tools), Connector-Anforderungen (welche OAuth-Anbieter benötigt werden) und Trigger-Vorlagen enthält. Synchronisierungs-Metadaten werden entfernt — das Paket ist ein sauberer, eigenständiger Bauplan.
Einen Agenten importieren:
POST /v1/agents/import
Content-Type: application/json
{
\"package\": {
\"$schema\": \"caiioo.agent.package/v1\",
\"agent\": {
\"id\": \"geteilter-forschungs-agent\",
\"branding\": { \"name\": \"Forschungs-Agent\", \"description\": \"Vom Team\" },
\"defaultSettings\": { \"systemPrompt\": \"Du erforschst Dinge.\" },
\"settingLevels\": {}
},
\"toolRequirements\": [
{ \"toolId\": \"web_browsing\", \"enabled\": true },
{ \"toolId\": \"search_tools\", \"enabled\": true }
]
}
}
Gibt 201 mit dem installierten Agenten zurück. ID-Kollisionen mit integrierten oder vorhandenen Agenten geben 409 zurück.
Fehlerbehandlung
Die API verwendet Standard-HTTP-Statuscodes:
| Code | Bedeutung |
|---|---|
200 |
Erfolg |
201 |
Erstellt |
202 |
Akzeptiert (asynchrone Operation gestartet) |
204 |
Gelöscht (kein Inhalt) |
400 |
Ungültige Anfrage — Details finden Sie im Feld error |
401 |
Nicht autorisiert — Sitzungsgeheimnis fehlt oder ist ungültig |
403 |
Verboten — z. B. Versuch, einen integrierten Agenten zu ändern |
404 |
Nicht gefunden |
409 |
Konflikt — z. B. Agenten-ID existiert bereits |
422 |
Validierungsfehler — Eingabe entspricht nicht dem Tool-Schema |
429 |
Ratenbegrenzung — siehe Ratenlimits im Abschnitt Authentifizierung |
500 |
Serverfehler — prüfen Sie das Feld error |
501 |
Nicht implementiert — Funktion existiert, ist aber so nicht verfügbar |
503 |
Dienst nicht verfügbar — Speicher oder Anbieter nicht bereit |
Alle Fehlermeldungen enthalten { "error": "lesbare Nachricht" }.
Schnellstart-Beispiel
Hier ist ein vollständiger Workflow: Erstellen Sie einen Agenten, führen Sie ihn aus und streamen Sie die Ergebnisse.
# 1. Einen benutzerdefinierten Agenten erstellen
curl -X POST http://localhost:3847/v1/agents \
-H "Authorization: Bearer $API_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"id": "quick-summarizer",
"branding": { "name": "Quick Summarizer" },
"defaultSettings": {
"systemPrompt": "Fasse jede Eingabe prägnant in 3 Stichpunkten zusammen.",
"enabledTools": { "web_browsing": true }
},
"settingLevels": {}
}'
# 2. Asynchron ausführen
RUN=$(curl -s -X POST http://localhost:3847/v1/runs \
-H "Authorization: Bearer $API_TOKEN" \
-H "Content-Type: application/json" \
-d '{ "agentId": "quick-summarizer", "input": { "message": "Fasse https://de.wikipedia.org/wiki/Künstliche_Intelligenz zusammen" }, "mode": "async" }')
RUN_ID=$(echo $RUN | jq -r '.runId')
# 3. Ereignisse streamen
curl -N http://localhost:3847/v1/runs/$RUN_ID/events \
-H "Authorization: Bearer $API_TOKEN"
# 4. Agenten zum Teilen exportieren
curl -X POST http://localhost:3847/v1/agents/quick-summarizer/export \
-H "Authorization: Bearer $API_TOKEN"
This guide is maintained by the Caiioo team using Slate, our built-in editor.