Niniejszy dokument jest automatycznym tłumaczeniem oryginału w języku angielskim. W przypadku jakichkolwiek rozbieżności między tym tłumaczeniem a oryginalną wersją angielską, wersja angielska jest rozstrzygająca. Przeczytaj oryginał w języku angielskim


Publiczne API

Caiioo zawiera API REST, które pozwala programowo kontrolować wszystko: uruchamiać agentów, zarządzać narzędziami, planować zadania i nie tylko. API znajduje się na tym samym lokalnym serwerze, który zasila aplikację desktopową i most przeglądarki.

Base URL: http://localhost:3847/v1

Uwierzytelnianie: Dwa sposoby uwierzytelniania, oba zależne od przełącznika API w ustawieniach:

Dla zewnętrznych konsumentów (skrypty, integracje, curl): Ustaw token dostępu API w Ustawienia > Dostęp API, a następnie używaj go jako tokenu Bearer:

curl -H \"Authorization: Bearer TWOJ_TOKEN_API\" http://localhost:3847/v1/providers

Dla aplikacji lokalnej (automatycznie): Aplikacja desktopowa Caiioo, rozszerzenia przeglądarki i aplikacje mobilne uwierzytelniają się automatycznie za pomocą istniejącego nagłówka relay auth (x-relay-auth). Nie jest wymagana ręczna konfiguracja — aplikacja zajmuje się tym za kulisami. Żądania relay-auth omijają przełącznik „Włącz publiczne API”, ponieważ są już zaufane; tylko żądania z tokenem bearer są blokowane przez przełącznik.

Konfiguracja:

  1. Otwórz Caiioo Ustawienia > Dostęp API
  2. Włącz Włącz publiczne API
  3. Ustaw token dostępu API (dowolny wybrany ciąg znaków — traktuj go jak hasło)
  4. Używaj tego tokenu we wszystkich żądaniach API

API jest dostępne na localhost i przez prywatny przekaźnik. Sprawdź GET /v1/auth/info (nie wymaga uwierzytelniania), aby poznać aktualny status i instrukcje konfiguracji.

Limity żądań: każde żądanie /v1/* jest limitowane na IP klienta — 100 żądań GET na minutę dla odczytów i 30 żądań zapisu na minutę (POST / PATCH / DELETE) łącznie. Żądania ponad limit otrzymują kod 429. Dostawy webhooków (POST /v1/webhooks/:id) nie wymagają autoryzacji bearer i nie podlegają tym limitom.

Profile

Jedno urządzenie może obsługiwać wiele profili użytkowników (np. osobisty + służbowy). API pozwala zewnętrznym skryptom sprawdzać dostępne profile i przełączać aktywny przed wykonaniem innych zadań. Tworzenie, aktualizacja i usuwanie profili celowo nie są dostępne przez publiczne API — te procesy należą do interfejsu onboardingu aplikacji.

Lista profili:

GET /v1/profiles

Zwraca { profiles: [...] } z jednym wpisem dla każdego nieusuniętego profilu. Każdy wpis zawiera id, name, email, avatarUrl, tier, accessibleModes, license, organization, preferences, onboardingComplete, createdAt, lastAccessedAt. Pola zawierające tokeny (serviceCredentials, oauthConnections) oraz wewnętrzne dane synchronizacji (vectorClock, lastModifiedBy) są usuwane. Użyj /v1/connectors, aby sprawdzić połączenia OAuth.

Pobierz aktywny profil:

GET /v1/profiles/active

Zwraca { profile } dla profilu aktualnie używanego przez ten serwer. Wszystkie zasoby /v1/* przypisane do profilu (wątki, załączniki, ustawienia, umiejętności) działają w kontekście tego profilu.

Przełącz aktywny profil:

PUT /v1/profiles/active
Content-Type: application/json

{ "profileId": "user-uuid-z-listy" }

Zwraca { profile } dla nowo aktywowanego profilu. Zwraca 404, jeśli ID nie odpowiada żadnemu znanemu profilowi.

Dostawcy i Modele

Dowiedz się, którzy dostawcy LLM są skonfigurowani i jakie modele są dostępne.

Lista dostawców:

GET /v1/providers

Zwraca każdy obsługiwany typ dostawcy. Obecnie: anthropic, openai, google, openrouter, ollama, poe, mlx, perplexity, baseten, cloudflare. Każdy wpis zawiera type, displayName, icon, requiresApiKey, hasApiKey oraz obiekt capabilities z poniższymi flagami.

Flaga uprawnień Znaczenie
supportsVision Dostawca może przyjmować obrazy jako dane wejściowe
supportsPdfFile Dostawca natywnie akceptuje bloki zawartości plików PDF
supportsToolCalling Dostawca obsługuje wywoływanie funkcji/narzędzi
supportsStreaming Dostawca przesyła tokeny strumieniowo w sposób przyrostowy
supportsExtendedThinking Dostawca udostępnia budżet na rozumowanie/myślenie
supportsPromptCaching Dostawca obsługuje dyrektywy buforowania promptów
nativeReasoningBlocks Dostawca emituje myślenie jako natywne bloki wiadomości (zamiast tekstu)
requiresThoughtSignature Dostawca wymaga, aby podpisane tokeny myśli były odsyłane z powrotem

Flagi uprawnień odzwierciedlają pole readonly capabilities każdej klasy dostawcy (zobacz src/shared/providers/*-provider.ts) i są weryfikowane przez test typu drift sentinel — należy wywoływać ten punkt końcowy w czasie wykonywania programu, zamiast kodować macierz na sztywno.

Uwagi dla dostawców BYOK:

  • perplexity udostępnia wyselekcjonowaną listę modeli Sonar (Perplexity nie posiada publicznego punktu końcowego /models).
  • cloudflare (AI Gateway) to model BYOK + wielu dostawców; lista modeli jest określana przez konfigurację Twojej bramy i jest zwracana jako pusta tablica przez /v1/providers/cloudflare/models. Należy korzystać z własnego katalogu bramy.

Lista modeli dla dostawcy:

GET /v1/providers/openrouter/models

Zwraca katalog modeli dla danego dostawcy. Każdy model zawiera id, displayName oraz contextLength, jeśli są dostępne. Zwraca błąd 503, gdy dostawca nie posiada klucza API lub jego nadrzędny katalog jest nieosiągalny.

Płaski katalog wszystkich dostawców:

GET /v1/models

Łączy modele od każdego skonfigurowanego dostawcy w jedną listę. Dostawcy bez kluczy API są pomijani i wymieniani w sekcji warnings.

Agenci

Agenci stanowią serce caiioo. Każdy agent to Tryb — skonfigurowana osobowość z własnym promptem systemowym, narzędziami, zmiennymi i umiejętnościami.

Lista wszystkich agentów:

GET /v1/agents

Zwraca wbudowanych agentów (Shopping, Workplace, General) oraz wszystkich utworzonych przez Ciebie agentów niestandardowych. Każdy jest oznaczony jako source: \"builtin\" lub source: \"custom\".

Utwórz niestandardowego agenta:

POST /v1/agents
Content-Type: application/json

{
  \"id\": \"my-research-agent\",
  \"branding\": {
    \"name\": \"Research Agent\",
    \"description\": \"Przeszukuje sieć i podsumowuje znaleziska\"
  },
  \"defaultSettings\": {
    \"systemPrompt\": \"Jesteś asystentem badawczym. Zawsze podawaj źródła.\",
    \"enabledTools\": { \"web_browsing\": true, \"search_tools\": true }
  },
  \"settingLevels\": {}
}

Zwraca 201 z utworzonym agentem. Zegar wektorowy jest dołączany automatycznie na potrzeby synchronizacji.

Zaktualizuj agenta:

PATCH /v1/agents/my-research-agent
Content-Type: application/json

{ \"branding\": { \"name\": \"Research Agent\", \"description\": \"Zaktualizowany opis\" } }

Łączy poprawkę z istniejącym agentem i aktualizuje zegar wektorowy. Wbudowani agenci zwracają 403 — są tylko do odczytu.

Usuń agenta:

DELETE /v1/agents/my-research-agent

Usuwanie miękkie przez „tombstone” (synchronizuje się między urządzeniami). Zwraca 204.

Uruchamianie Agentów

To jest główne zdarzenie — wywołanie agenta w celu przetworzenia wiadomości.

Treść żądania — obsługiwane pola

Pole Wymagane Opis
agentId tak ID wbudowanego trybu (np. general) lub ID niestandardowego agenta
input.message tak Tekst wiadomości użytkownika
input.attachments nie Tablica identyfikatorów załączników (uprzednio przesłanych przez /v1/attachments), które mają zostać dołączone do tej tury
input.variables nie Nadpisania zmiennych dla danego uruchomienia, scalane z resolverem zmiennych agenta
input.tabContext nie Dowolny ciąg znaków wstrzykiwany jako kontekst strony (używany przez mostek przeglądarki)
input.messageId nie ID wiadomości dostarczone przez klienta — przydatne do deduplikacji w przypadku ponowień
threadId nie Istniejący wątek do kontynuacji. Jeśli zostanie pominięty, zostanie utworzony i zwrócony nowy wątek
mode nie "sync" lub "async". Domyślnie "async"

Tryb synchroniczny

Oczekiwanie na pełną odpowiedź:

POST /v1/runs
Content-Type: application/json

{
  "agentId": "general",
  "input": { "message": "Jaka jest dzisiaj pogoda w Paryżu?" },
  "mode": "sync"
}

Zwraca 200 wraz z { content, usage, status: "completed" } po zakończeniu pracy agenta. Jeśli agent napotka błąd, zwraca 500 wraz z { error, status: "error" }. Uruchomienia synchroniczne ulegają przedawnieniu po 5 minutach ze statusem status: "error", jeśli nie zostanie odebrane zdarzenie końcowe — dla zadań, które mogą trwać dłużej, należy użyć trybu async + SSE.

Tryb asynchroniczny

Wyślij i zapomnij — przydatne w przypadku długotrwałych zadań:

POST /v1/runs
Content-Type: application/json

{
  "agentId": "my-research-agent",
  "input": { "message": "Napisz analizę trendów w energii odnawialnej na 2000 słów" },
  "mode": "async"
}

Natychmiast zwraca 202 wraz z { runId, threadId, status: "running" }.

Sprawdzanie statusu (polling):

GET /v1/runs/{runId}

Zwraca { run: { runId, threadId, agentId, status, createdAt, content?, usage?, error? } }. Status to jeden z: running, completed, error lub cancelled.

Strumieniowanie zdarzeń w czasie rzeczywistym (SSE):

GET /v1/runs/{runId}/events

Zwraca text/event-stream z każdym zdarzeniem agenta w miarę ich występowania: GENERATION_STARTED, STREAMING_CONTENT, wywołania narzędzi, aktywność podagentów oraz zdarzenie końcowe (GENERATION_COMPLETE, GENERATION_ERROR lub GENERATION_CANCELLED).

Po zdarzeniu końcowym serwer emituje jedną ostatnią ramkę SSE z event: terminal i pustym ładunkiem danych jako jawny znacznik końca strumienia, a następnie zamyka połączenie. Klienci powinni traktować otrzymanie tej ramki (lub zamknięcie połączenia) jako sygnał do zakończenia odczytu.

Jeśli zasubskrybujesz po zakończeniu uruchomienia, serwer odtworzy jedną ramkę typu RUN_SNAPSHOT zawierającą pełny końcowy rekord record, po której nastąpi znacznik event: terminal, a następnie zamknie połączenie.

Anulowanie uruchomienia:

POST /v1/runs/{runId}/cancel

Zwraca { run: { ..., status: "cancelled" } }.

Wątki (Threads)

Wątki to rozmowy. Każde uruchomienie agenta odbywa się w ramach wątku, a wątki są zachowywane między sesjami. API pozwala na programowe listowanie, odczytywanie, tworzenie i zarządzanie wątkami.

Lista wszystkich wątków (tylko metadane):

GET /v1/threads

Zwraca { threads: [...] } dla bieżącego profilu z usuniętym polem messages (użyj punktu końcowego szczegółów, gdy ich potrzebujesz). Wszystkie inne pola są zachowane — id, title, createdAt, updatedAt, modeId, archived, statystyki użycia, a także subAgentHistories, anonymizerSnapshot, threadToolApprovals, threadVariables, threadToolOverrides, messagingBinding, scheduledTaskId, jeśli są ustawione. (Bogatszy ładunek danych jest dostępny wyłącznie dla API — transmisja paska bocznego przez WebSocket używa większego ograniczenia danych, aby zmieścić się w limitach transportowych).

Pobieranie wątku z pełną listą wiadomości:

GET /v1/threads/{id}

Zwraca kompletny wątek wraz z tablicą messages — każdą wiadomość użytkownika, odpowiedź asystenta, wywołanie narzędzia i wynik działania narzędzia.

Pobieranie samych wiadomości:

GET /v1/threads/{id}/messages

Zwraca tylko tablicę messages — lżejszą niż pełny obiekt wątku, gdy potrzebujesz tylko samej rozmowy.

Tworzenie wątku:

POST /v1/threads
Content-Type: application/json

{ "title": "Research project", "modeId": "general" }

Zwraca 201 wraz z { thread }. Nowy wątek pojawia się natychmiast na pasku bocznym (poprzez transmisję WebSocket). API nigdy nie przełącza aktywnego wątku aplikacji przy tworzeniu — jeśli tego chcesz, wywołaj oddzielnie PUT /v1/threads/active.

Aktualizacja wątku:

PATCH /v1/threads/{id}
Content-Type: application/json

{ "title": "Renamed project", "archived": true }

Pola podlegające aktualizacji: title, modeId, archived, lastUsedModel. Zmiany są transmitowane do paska bocznego w czasie rzeczywistym.

Usuwanie wątku:

DELETE /v1/threads/{id}

Wykonuje miękkie usunięcie wątku (znacznik usunięcia dla synchronizacji). Zwraca 204. Usunięte wątki trafiają do kosza i mogą zostać odzyskane do momentu opróżnienia kosza.

Aktywny wątek:

GET /v1/threads/active            # Zwraca { threadId }
PUT /v1/threads/active            # Body: { "threadId": "..." }

Zarządzanie koszem:

GET /v1/threads/trash/count       # Zwraca { count }
POST /v1/threads/trash/empty      # Zwraca { deletedCount, protectedCount }

Wątki chronione (zachowane poprzez przełącznik retencji danych) są wyłączone z procesu opróżniania kosza.

Kontynuowanie rozmowy przez API: Aby wysłać kolejną wiadomość w istniejącym wątku, użyj POST /v1/runs z identyfikatorem wątku:

POST /v1/runs
Content-Type: application/json

{
  "agentId": "general",
  "threadId": "existing-thread-id",
  "input": { "message": "Follow up on that last point" },
  "mode": "sync"
}

Agent widzi pełną historię rozmowy z danego wątku.

Załączniki

Załączniki to pliki powiązane z wątkami — zrzuty ekranu, pliki PDF, dokumenty, przesłane obrazy, wygenerowane artefakty. API pozwala na ich listowanie, przesyłanie, pobieranie i zarządzanie nimi.

Lista wszystkich załączników (tylko metadane):

GET /v1/attachments

Zwraca metadane załączników dla bieżącego profilu. Ciężkie pola (dataUrl, extractedContent, extractedImages) są usuwane — użyj punktów końcowych szczegółów lub treści, aby je uzyskać.

Lista załączników dla konkretnego wątku:

GET /v1/threads/{threadId}/attachments

Pobierz metadane załącznika:

GET /v1/attachments/{id}

Zwraca pełne metadane, w tym extractedContent (tekst OCR, przetworzony markdown), contentType, fileName, size oraz flagę hasContent. Surowe dane binarne NIE są dołączone — użyj punktu końcowego /content.

Pobierz plik binarny załącznika:

GET /v1/attachments/{id}/content

Zwraca surowy plik z poprawnymi nagłówkami Content-Type i Content-Disposition. Przekieruj to do pliku:

curl -o wyjscie.pdf \
  -H "Authorization: Bearer $API_TOKEN" \
  http://localhost:3847/v1/attachments/{id}/content

Prześlij załącznik:

POST /v1/attachments
Content-Type: application/json

{
  "threadId": "thread-id",
  "type": "user_upload",
  "contentType": "application/pdf",
  "fileName": "raport.pdf",
  "description": "Raport kwartalny",
  "dataUrl": "data:application/pdf;base64,JVBERi0xLjQ..."
}

dataUrl to adres URL danych zakodowany w base64. Zwraca 201 z nowym ID załącznika. Załącznik jest powiązany z określonym wątkiem.

Aktualizuj metadane załącznika:

PATCH /v1/attachments/{id}
Content-Type: application/json

{ "description": "Zaktualizowany opis", "fileName": "nowa-nazwa.pdf" }

Usuń załącznik:

DELETE /v1/attachments/{id}

Usuwanie miękkie przez znacznik tombstone. Zwraca 204.

Serwery MCP

Zarządzaj połączeniami z serwerami MCP (Model Context Protocol) — serwerami, które zapewniają agentom dostęp do zewnętrznych narzędzi i źródeł danych.

Lista skonfigurowanych serwerów:

GET /v1/mcp-servers

Zwraca wszystkie konfiguracje serwerów MCP dla bieżącego profilu. Pola wrażliwe (authToken, env, credentialId) są usuwane z odpowiedzi.

Pobierz konfigurację serwera:

GET /v1/mcp-servers/{id}

Dodaj nowy serwer MCP:

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"
}

W przypadku zdalnych serwerów HTTP użyj "url" zamiast "command":

{
  "id": "remote-server",
  "name": "Remote API",
  "url": "https://my-mcp-server.example.com/sse",
  "serverType": "remote"
}

Opcjonalne pola akceptowane w POST: command, args, env, url, description, transportType, authType, authToken, authHeader, headers, specType, specPath, timeoutMs, credentialId, oauthConnectionId, approval. Pola zarządzane przez serwer (customOAuth, hubPackageId, profileId, connectorId, teamPublished, teamOrgId, vectorClock, ...) nie mogą być ustawiane przez API.

Zaktualizuj serwer:

PATCH /v1/mcp-servers/{id}
Content-Type: application/json

{ "name": "Renamed Server", "args": ["-y", "@mcp/server-v2"] }

Pola możliwe do edycji (patchable) odpowiadają liście dozwolonych pól POST (w tym credentialId i oauthConnectionId — przydatne do rotacji połączenia OAuth bez konieczności usuwania i ponownego tworzenia). Pola zarządzane przez serwer pozostają tylko do odczytu.

Włącz/wyłącz serwer:

POST /v1/mcp-servers/{id}/toggle
Content-Type: application/json

{ "enabled": false }

Usuń serwer:

DELETE /v1/mcp-servers/{id}

Zarządzanie procesami

W przypadku lokalnych (stdio) serwerów MCP można bezpośrednio zarządzać procesem serwera.

Lista uruchomionych procesów:

GET /v1/mcp-servers/processes

Zwraca uruchomione procesy serwera wraz z pid, startedAt oraz statusem running.

Uruchom serwer:

POST /v1/mcp-servers/{id}/start

Odczytuje command/args/env z konfiguracji serwera i uruchamia proces. Zwraca status procesu.

Zatrzymaj serwer:

POST /v1/mcp-servers/{id}/stop

Bezpiecznie zamyka proces serwera (SIGTERM z opcją awaryjną SIGKILL).

Wywołaj metodę JSON-RPC bezpośrednio:

POST /v1/mcp-servers/{id}/call
Content-Type: application/json

{ "method": "tools/list", "params": {} }

Wysyła surowe żądanie JSON-RPC 2.0 do serwera i zwraca wynik. Przydatne do debugowania lub wywoływania metod nieudostępnionych przez API narzędzi.

Narzędzia i zestawy narzędzi (Tools & Toolkits)

Przeglądaj i wywołuj narzędzia, z których korzystają agenci — przeglądanie stron internetowych, wyszukiwanie, kalendarz, Gmail, Slate i inne.

Lista zestawów narzędzi (pogrupowana):

GET /v1/toolkits

Zwraca wbudowane narzędzia pogrupowane według kategorii (Productivity, Search, Utilities itp.) oraz wszelkie podłączone serwery MCP jako oddzielne zestawy narzędzi, każdy z listą dostępnych akcji.

Lista wszystkich narzędzi (płaska):

GET /v1/tools
GET /v1/tools?source=embedded   # Tylko wbudowane narzędzia
GET /v1/tools?source=mcp        # Tylko narzędzia serwera MCP

Pobierz szczegóły narzędzia ze schematem wejściowym:

GET /v1/tools/calculator

Zwraca { tool: { name, displayName, description, source, category, inputSchema, actions?, requiredTier?, requiredRuntimes?, riskTier?, riskExplanation?, requiresApproval? } }.

Pole Znaczenie
inputSchema Schemat JSON dla danych wejściowych narzędzia — należy go zweryfikować przed wywołaniem
actions Opcjonalne pod-akcje (np. Slate read/write); każda posiada id, displayName, description, opcjonalne requiredTier
requiredTier Minimalny poziom subskrypcji użytkownika (free, jeśli pominięto). Wywołania przez publiczne API odrzucają wszystko powyżej free
requiredRuntimes Platformy, na których to narzędzie jest dostępne (macos, ios itp.); pominięcie ⇒ dostępne wszędzie
riskTier Ryzyko wymagające zgody: low (domyślne), medium, high
riskExplanation Czytelny dla człowieka powód podwyższonego poziomu riskTier
requiresApproval true, gdy narzędzie wymaga zatwierdzenia przez użytkownika przy każdym wywołaniu — wywołania przez publiczne API odrzucają te narzędzia

Wywołaj narzędzie bezpośrednio:

POST /v1/tools/calculator/invoke
Content-Type: application/json

{ "input": { "expression": "sqrt(144) + 3^2" }, "threadId": "optional-thread-id" }

Zwraca { result }. Dane wejściowe są weryfikowane pod kątem schematu narzędzia — nieprawidłowe dane zwracają błąd 422 ze szczegółami. Przekaż opcjonalny threadId, jeśli narzędzie wymaga kontekstu ograniczonego do wątku (np. wyszukiwanie załączników).

Ograniczenia — co odrzuca publiczne API:

  • Narzędzia ograniczone poziomem subskrypcji (metadata.requiredTier !== 'free') → 403. Pętla agenta sprawdza poziom subskrypcji względem sesji użytkownika; publiczne API nie posiada kontekstu subskrypcji, więc konserwatywna polityka nakazuje odmowę. Zamiast tego użyj POST /v1/runs z agentem o odpowiednim poziomie subskrypcji.
  • Narzędzia wymagające zatwierdzenia (metadata.approval.requiresApproval === true) → 403. W procesie brakuje człowieka, którego można by zapytać o zgodę. Wywołaj przez POST /v1/runs (co wyświetli monit użytkownikowi) lub ustaw tryb zatwierdzania narzędzi na approve_all w aplikacji, aby to pominąć.
  • Zdalne narzędzia MCP501 z instrukcją użycia /v1/runs (wymagają one transportu podprocesu agenta).

Narzędzia wizyjne i wykorzystujące obrazy: najpierw prześlij plik przez POST /v1/attachments, a następnie przekaż zwrócony identyfikator załącznika wewnątrz input (np. { "input": { "attachment_id": "att_abc", "prompt": "Co jest na tym obrazku?" } }). Narzędzie odczytuje dane binarne z magazynu za pomocą threadId; nie przekazuje się bajtów bezpośrednio w treści żądania.

Konektory

Zarządzaj integracjami OAuth — Google, Microsoft, GitHub, Notion, Slack i inne.

Przeglądaj dostępne integracje:

GET /v1/connectors/catalog

Zwraca wszystkich zarejestrowanych dostawców OAuth wraz z ich nazwą, kategorią i domyślnymi zakresami.

Lista połączonych kont:

GET /v1/connectors

Zwraca aktywne połączenia dla bieżącego profilu. Tokeny nigdy nie są ujawniane — tylko metadane (dostawca, e-mail, status, zakresy, znaczniki czasu).

Pobierz pojedyncze połączenie:

GET /v1/connectors/{id}

Zwraca metadane dla jednego połączenia. Tokeny nigdy nie są ujawniane.

Sprawdź stan połączenia:

POST /v1/connectors/{id}/test

Zwraca { health: { status, isTokenExpired, canRefresh } }.

Usuń połączenie:

DELETE /v1/connectors/{id}

Tworzenie nowych połączeń wymaga interaktywnego procesu OAuth przez interfejs aplikacji lub ścieżki /auth/*.

Wyzwalacze

Planuj automatyczne uruchamianie agentów — codzienne podsumowania, cotygodniowe raporty, monitorowanie w odstępach czasu.

Każdy wyzwalacz ma dyskryminator kind: schedule (domyślny — uruchamiany zegarem), webhook (uruchamiany, gdy zewnętrzna usługa wyśle POST na ścieżkę webhooka) lub messaging (uruchamiany z połączonego adaptera wiadomości — np. przychodzące wiadomości Slack/Discord pasujące do filtra kanału).

Lista wyzwalaczy:

GET /v1/triggers

Zwraca { triggers: [...] }. Każdy wpis zawiera swój kind, harmonogram i pola specyficzne dla rodzaju (np. webhookSecret/webhookPath dla wyzwalaczy webhook).

Pobierz pojedynczy wyzwalacz:

GET /v1/triggers/{id}

Utwórz zaplanowany wyzwalacz:

POST /v1/triggers
Content-Type: application/json

{
  \"name\": \"Poranny raport\",
  \"prompt\": \"Podsumuj moje nieprzeczytane e-maile i dzisiejszy kalendarz\",
  \"modeId\": \"general\",
  \"schedule\": { \"type\": \"daily\", \"time\": \"08:00\" }
}

Wspierane typy harmonogramów:

  • { \"type\": \"interval\", \"minutes\": 60 } — co N minut (min 15, max 1440)
  • { \"type\": \"daily\", \"time\": \"09:00\" } — codziennie o określonej godzinie
  • { \"type\": \"weekly\", \"day\": \"mon\", \"time\": \"09:00\" } — co tydzień
  • { \"type\": \"weekdays\", \"time\": \"08:30\" } — od poniedziałku do piątku
  • { \"type\": \"daysOfWeek\", \"days\": [\"mon\", \"wed\", \"fri\"], \"time\": \"10:00\" } — w konkretne dni
  • { \"type\": \"monthly\", \"dayOfMonth\": 1, \"time\": \"09:00\" } — co miesiąc
  • { \"type\": \"manual\" } — tylko przy ręcznym wywołaniu przez API

Uruchom wyzwalacz ręcznie:

POST /v1/triggers/{id}/fire

Zwraca 202 z threadId dla wynikowego uruchomienia.

Aktualizacja lub usuwanie:

PATCH /v1/triggers/{id}
DELETE /v1/triggers/{id}

Webhooki

Triggery webhooków pozwalają usługom zewnętrznym (CI/CD, monitoring, kreatory formularzy) wyzwalać działanie agenta przez HTTP.

Utwórz trigger webhooka:

POST /v1/triggers
Content-Type: application/json

{
  "name": "Deploy hook",
  "prompt": "Wystąpił deploy: {{webhook.body}}",
  "modeId": "general",
  "kind": "webhook"
}

Zwraca 201 wraz z webhookSecret i webhookPath. Zapisz sekret — będzie potrzebny do podpisywania ładunków (payloads).

Wyślij webhook:

# Oblicz HMAC-SHA256 surowej treści żądania
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"}

Endpoint webhooka NIE wymaga autoryzacji bearer — zamiast tego używa weryfikacji HMAC. Zwraca 202 z threadId wysłanego zadania. Symbol zastępczy {{webhook.body}} w prompcie triggera jest zastępowany surową treścią żądania.

Triggery komunikatów

Triggery komunikatów (messaging triggers) uruchamiają się, gdy podłączony adapter (np. integracja Slack lub Discord zainstalowana przez Community Hub) otrzyma wiadomość przychodzącą pasującą do filtra. Utwórz za pomocą kind: "messaging":

POST /v1/triggers
Content-Type: application/json

{
  "name": "Mention responder",
  "prompt": "Odpowiedz pomocnie na: {{message.text}}",
  "modeId": "general",
  "kind": "messaging",
  "messagingAdapterId": "slack-team-acme",
  "messagingChannelFilter": "#support"
}

Adapter odpowiada za przesyłanie pasujących zdarzeń do triggera; messagingChannelFilter jest specyficzny dla danego adaptera.

Funkcje Niestandardowe

Twórz własne narzędzia, które agenci mogą wywoływać. Funkcje są pisane w JavaScript lub Python i wykonywane w piaskownicy (sandbox).

Lista funkcji:

GET /v1/functions

Utwórz funkcję:

POST /v1/functions
Content-Type: application/json

{
  "name": "calculate_bmi",
  "description": "Oblicz wskaźnik masy ciała BMI na podstawie wzrostu i wagi",
  "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"]
  }
}

Funkcje JavaScript otrzymują input i muszą zwrócić wynik. Funkcje Python ustawiają zmienną result:

# Przykład Python
result = {"bmi": round(input["weightKg"] / (input["heightM"] ** 2), 1)}

Wykonaj funkcję bezpośrednio:

POST /v1/functions/{id}/execute
Content-Type: application/json

{ "input": { "weightKg": 75, "heightM": 1.80 } }

Bezpieczeństwo: JavaScript działa w piaskownicy vm Node (brak dostępu do systemu plików i sieci, limit czasu 10s). Python działa jako podproces z limitem czasu 30s. Oba sprawdzają poprawność danych wejściowych przed wykonaniem.

Aktualizacja lub usuwanie:

PATCH /v1/functions/{id}
DELETE /v1/functions/{id}

Umiejętności (Skills)

Umiejętności to zapisane prompty, do których agenci mogą się odwoływać i które można szybko uruchomić z widoku nowej konwersacji. Umiejętności zainstalowane z Hub (zarządzane przez pakiety) NIE są tutaj uwzględnione — wymieniane i edytowalne są tylko umiejętności stworzone przez użytkownika.

Lista umiejętności:

GET /v1/skills

Zwraca { skills: [...] } umiejętności stworzonych przez użytkownika dla aktywnego profilu. Umiejętności usunięte (tombstoned), nakładki z Hub oraz cienie synchronizacji są odfiltrowane.

Pobierz jedną umiejętność:

GET /v1/skills/{id}

Utwórz umiejętność:

POST /v1/skills
Content-Type: application/json

{
  "prompt": "Podsumuj stronę w 3 punktach.",
  "tags": ["utility", "summarize"],
  "isFavorite": true,
  "modes": ["general"],
  "displayName": "Szybkie podsumowanie",
  "description": "Trzypunktowe TL;DR aktywnej strony"
}

Tylko pole prompt jest wymagane. modes (opcjonalne) ogranicza umiejętność do konkretnych ID agentów; pomiń dla wszystkich trybów. Zwraca 201 z nową umiejętnością (wraz z przypisanymi przez serwer id, createdAt, updatedAt).

Aktualizuj umiejętność:

PATCH /v1/skills/{id}
Content-Type: application/json

{ "prompt": "Zaktualizowany prompt", "isFavorite": false }

Pola możliwe do edycji: prompt, tags, modes, displayName, description, isFavorite. Próby edycji umiejętności będącej nakładką z Hub zwracają 404.

Usuń umiejętność:

DELETE /v1/skills/{id}

Miękkie usuwanie przez znacznik tombstone. Zwraca 204. Dla umiejętności z Hub zwraca 404 — zamiast tego należy odinstalować pakiet źródłowy.

Przepływy Pracy (Workflows)

Orkiestruj wielu agentów w grafie DAG (skierowany graf acykliczny) — uruchamiaj kroki równolegle tam, gdzie to możliwe, i przekazuj wyniki z wcześniejszych kroków do późniejszych.

Walidacja grafu przepływu pracy:

POST /v1/workflows/validate
Content-Type: application/json

{
  "graph": {
    "nodes": [
      { "id": "research", "agentId": "general", "prompt": "Zbadaj trendy w energii odnawialnej" },
      { "id": "analyze", "agentId": "general", "prompt": "Zbadaj ceny konkurencji" },
      { "id": "report", "agentId": "general", "prompt": "Napisz raport łączący: {{outputs.research}} i {{outputs.analyze}}", "dependsOn": ["research", "analyze"] }
    ]
  }
}

Zwraca { valid: true/false, errors: [...] }. Sprawdza pod kątem cykli, duplikatów ID i brakujących odniesień do zależności.

Wykonaj przepływ pracy:

POST /v1/workflows/execute
Content-Type: application/json

{
  "graph": {
    "nodes": [
      { "id": "research", "agentId": "general", "prompt": "Zbadaj trendy w energii odnawialnej" },
      { "id": "summarize", "agentId": "general", "prompt": "Podsumuj: {{outputs.research}}", "dependsOn": ["research"] }
    ]
  }
}

Zwraca { status: "completed", outputs: { research: "...", summarize: "..." }, nodeResults: {...} }.

Niezależne węzły (bez wspólnych zależności) działają równolegle. Symbol zastępczy {{outputs.nodeId}} w prompcie węzła jest zastępowany treścią wyjściową nazwanego węzła nadrzędnego. Każdy węzeł to pełne uruchomienie agenta, więc może używać narzędzi, przeglądać sieć i korzystać ze wszystkich możliwości docelowego agenta.

Bazy Wiedzy

Organizuj dokumenty w przeszukiwalne kolekcje, do których agenci mogą się odwoływać.

Lista baz wiedzy:

GET /v1/knowledge/bases

Utwórz bazę wiedzy:

POST /v1/knowledge/bases
Content-Type: application/json

{ "name": "Prace badawcze" }

Zwraca 201 z ID nowej bazy.

Prześlij dokument do bazy wiedzy:

POST /v1/knowledge/bases/{id}/documents
Content-Type: application/json

{
  "fileName": "research-paper.pdf",
  "contentType": "application/pdf",
  "dataUrl": "data:application/pdf;base64,JVBERi0xLjQ...",
  "description": "Trendy energii odnawialnej 2026"
}

Pole dataUrl to adres URL danych zakodowany w base64. Zwraca 201 z metadanymi dokumentu.

Lista dokumentów w bazie wiedzy:

GET /v1/knowledge/bases/{id}/documents

Szukaj wewnątrz bazy wiedzy:

POST /v1/knowledge/bases/{id}/search
Content-Type: application/json

{ "query": "energia odnawialna" }

Zwraca pasujące dokumenty na podstawie nazwy pliku i opisu. Wyszukiwanie semantyczne (wektorowe) pojawi się w przyszłej wersji.

Usuń dokument lub bazę wiedzy:

DELETE /v1/knowledge/bases/{id}/documents/{docId}
DELETE /v1/knowledge/bases/{id}

Eksport i import agentów

Udostępniaj agentów jako przenośne pakiety — między urządzeniami, zespołami lub przez Community Hub.

Eksportuj agenta:

POST /v1/agents/{id}/export

Zwraca pakiet JSON zawierający definicję agenta, wymagania dotyczące narzędzi (pochodne włączonych narzędzi), wymagania dotyczące konektorów (którzy dostawcy OAuth są potrzebni) oraz szablony wyzwalaczy. Metadane synchronizacji są usuwane — pakiet jest czystym, autonomicznym schematem.

Importuj agenta:

POST /v1/agents/import
Content-Type: application/json

{
  \"package\": {
    \"$schema\": \"caiioo.agent.package/v1\",
    \"agent\": {
      \"id\": \"shared-research-agent\",
      \"branding\": { \"name\": \"Research Agent\", \"description\": \"Od zespołu\" },
      \"defaultSettings\": { \"systemPrompt\": \"Badasz różne rzeczy.\" },
      \"settingLevels\": {}
    },
    \"toolRequirements\": [
      { \"toolId\": \"web_browsing\", \"enabled\": true },
      { \"toolId\": \"search_tools\", \"enabled\": true }
    ]
  }
}

Zwraca 201 z zainstalowanym agentem. Konflikty ID z wbudowanymi lub istniejącymi agentami zwracają 409.

Obsługa błędów

API używa standardowych kodów statusu HTTP:

Kod Znaczenie
200 Sukces
201 Utworzono
202 Zaakceptowano (operacja asynchroniczna rozpoczęta)
204 Usunięto (brak treści)
400 Błędne żądanie — sprawdź pole error, aby poznać szczegóły
401 Nieautoryzowany — brak lub nieprawidłowy sekret sesji
403 Zabroniony — np. próba modyfikacji wbudowanego agenta
404 Nie znaleziono
409 Konflikt — np. ID agenta już istnieje
422 Błąd walidacji — dane wejściowe nie pasują do schematu narzędzia
429 Przekroczono limit zapytań — zobacz limity w sekcji Autoryzacja
500 Błąd serwera — sprawdź pole error
501 Nie zaimplementowano — funkcja istnieje, ale nie jest dostępna w ten sposób
503 Usługa niedostępna — magazyn danych lub dostawca nie jest gotowy

Wszystkie odpowiedzi o błędach zawierają { "error": "czytelny dla człowieka komunikat" }.

Przykład Szybkiego Startu

Oto kompletny przepływ pracy: utwórz agenta, uruchom go i strumieniuj wyniki.

# 1. Utwórz niestandardowego agenta
curl -X POST http://localhost:3847/v1/agents \
  -H "Authorization: Bearer $API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "id": "quick-summarizer",
    "branding": { "name": "Szybki Podsumowywacz" },
    "defaultSettings": {
      "systemPrompt": "Podsumuj wszelkie dane wejściowe zwięźle w 3 punktach.",
      "enabledTools": { "web_browsing": true }
    },
    "settingLevels": {}
  }'

# 2. Uruchom go asynchronicznie
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": "Podsumuj https://pl.wikipedia.org/wiki/Sztuczna_inteligencja" }, "mode": "async" }')

RUN_ID=$(echo $RUN | jq -r '.runId')

# 3. Strumieniuj zdarzenia
curl -N http://localhost:3847/v1/runs/$RUN_ID/events \
  -H "Authorization: Bearer $API_TOKEN"

# 4. Eksportuj agenta do udostępnienia
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.