Це машинний переклад оригінального документа англійською мовою. У разі будь-яких розбіжностей між цим перекладом та оригінальною англійською версією, пріоритет має версія англійською мовою. Читати оригінал англійською мовою


Публічний API

Caiioo містить REST API, який дозволяє керувати всім програмно: запускати агентів, керувати інструментами, планувати завдання тощо. API працює на тому ж локальному сервері, що й десктопний застосунок та розширення для браузера.

Базовий URL: http://localhost:3847/v1

Автентифікація: два способи автентифікації, обидва регулюються перемикачем API в налаштуваннях:

Для зовнішніх клієнтів (скрипти, інтеграції, curl): Встановіть токен доступу до API в розділі Налаштування > Зв'язок > Доступ до API, а потім використовуйте його як Bearer-токен:

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

Для локального застосунку (автоматично): Десктопний застосунок Caiioo, розширення для браузера та мобільні застосунки автентифікуються автоматично через наявний заголовок автентифікації реле (x-relay-auth; заголовки HTTP нечутливі до регістру). Ручне налаштування не потрібне — застосунок обробляє це у фоновому режимі. Запити з relay-auth оминають перемикач Увімкнути публічний API, оскільки вони вже є довіреними; перемикач блокує лише запити з bearer-токеном.

Налаштування: Доступ до API — це функція Pro; розділ «Доступ до API» з'являється в Налаштуваннях після переходу на Pro.

  1. Відкрийте Налаштування Caiioo > Зв'язок > Доступ до API
  2. Увімкніть Увімкнути публічний API
  3. Встановіть токен доступу до API (будь-який рядок на ваш вибір — ставтеся до нього як до пароля)
  4. Використовуйте цей токен у всіх запитах до API

API доступний на localhost та через приватне реле. Перевірте GET /v1/auth/info (автентифікація не потрібна), щоб дізнатися поточний стан та інструкції з налаштування.

Ліміти запитів: кожен запит до /v1/* має обмеження на IP-адресу клієнта — 100 GET-запитів на хвилину для читання та 30 запитів на зміну на хвилину (POST / PATCH / DELETE) сумарно. Запити понад ліміт отримують 429. Доставлення вебхуків (POST /v1/webhooks/:id) не потребує bearer-автентифікації та не підпадає під ці ліміти.

Профілі

Один пристрій може містити кілька профілів користувачів (наприклад, особистий + робочий). API дозволяє зовнішнім скриптам переглядати доступні профілі та перемикати активний перед виконанням іншої роботи. Створення, оновлення та видалення профілів навмисно не винесені в публічний API — ці процеси належать до інтерфейсу налаштування програми.

Список профілів:

GET /v1/profiles

Повертає { profiles: [...] } з одним записом для кожного невидаленого профілю. Кожен запис містить id, name, email, avatarUrl, tier, accessibleModes, license, organization, preferences, onboardingComplete, createdAt, lastAccessedAt. Поля з токенами (serviceCredentials, oauthConnections) та внутрішні дані синхронізації (vectorClock, lastModifiedBy) видалені. Використовуйте /v1/connectors для перегляду підключень OAuth.

Отримати активний профіль:

GET /v1/profiles/active

Повертає { profile } для профілю, який зараз використовується цим сервером. Усі ресурси /v1/*, прив'язані до профілю (гілки, вкладення, налаштування, навички), працюють з цим профілем.

Змінити активний профіль:

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

{ "profileId": "user-uuid-from-list" }

Повертає { profile } для нового активного профілю. Повертає 404, якщо ID не відповідає жодному відомому профілю.

Провайдери та моделі

Дізнайтеся, які провайдери LLM налаштовані та які моделі доступні.

Список провайдерів:

GET /v1/providers

Повертає всі підтримувані типи провайдерів. Наразі: anthropic, openai, google, openrouter, ollama, poe, mlx, perplexity, baseten, cloudflare. Кожен запис містить type, displayName, icon, requiresApiKey, hasApiKey та об'єкт capabilities із прапорцями, наведеними нижче.

Прапорець можливостей Значення
supportsVision Провайдер може приймати зображення на вхід
supportsPdfFile Провайдер може приймати блоки вмісту файлів PDF нативно
supportsToolCalling Провайдер підтримує виклик функцій/інструментів
supportsStreaming Провайдер передає токени потоково (інкрементально)
supportsExtendedThinking Провайдер надає бюджет для міркування/мислення
supportsPromptCaching Провайдер підтримує директиви кешування промптів
nativeReasoningBlocks Провайдер видає міркування як нативні блоки повідомлень (а не текст)
requiresThoughtSignature Провайдер вимагає повернення підписаних токенів міркування

Прапорці можливостей дублюють поле readonly capabilities кожного класу провайдера (див. src/shared/providers/*-provider.ts) і перевіряються тестом на відповідність — викликайте цей ендпоінт під час виконання, а не використовуйте жорстко закодовану матрицю.

Примітки для BYOK провайдерів:

  • perplexity надає кураторський список моделей Sonar (Perplexity не має публічного ендпоінту /models).
  • cloudflare (AI Gateway) — це BYOK + мульти-вендор; список моделей визначається конфігурацією вашого шлюзу і повертається як порожній масив через /v1/providers/cloudflare/models. Використовуйте власний каталог шлюзу.

Список моделей для провайдера:

GET /v1/providers/openrouter/models

Повертає каталог моделей для цього провайдера. Кожна модель містить id, displayName та contextLength, де це можливо. Повертає 503, якщо у провайдера відсутній API ключ або його висхідний каталог недоступний.

Загальний каталог усіх провайдерів:

GET /v1/models

Об'єднує моделі від кожного налаштованого провайдера в один список. Провайдери без API ключів ігноруються та вказуються у warnings.

Агенти

Агенти — це ядро caiioo. Кожен агент — це Режим, налаштована особистість зі своєю системною підказкою, інструментами, змінними та навичками.

Список усіх агентів:

GET /v1/agents

Повертає вбудованих агентів (Shopping, Workplace, General) та будь-яких створених вами агентів. Кожен позначений тегом source: \"builtin\" або source: \"custom\".

Створити власного агента:

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

{
  \"id\": \"my-research-agent\",
  \"branding\": {
    \"name\": \"Research Agent\",
    \"description\": \"Шукає в мережі та підсумовує результати\"
  },
  \"defaultSettings\": {
    \"systemPrompt\": \"Ви — асистент-дослідник. Завжди цитуйте джерела.\",
    \"enabledTools\": { \"web_browsing\": true, \"search_tools\": true }
  },
  \"settingLevels\": {}
}

Повертає 201 зі створеним агентом. Векторний годинник додається автоматично для синхронізації.

Оновити агента:

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

{ \"branding\": { \"name\": \"Research Agent\", \"description\": \"Оновлений опис\" } }

Об'єднує патч з існуючим агентом та оновлює векторний годинник. Вбудовані агенти повертають 403 — вони доступні лише для читання.

Видалити агента:

DELETE /v1/agents/my-research-agent

М'яке видалення через tombstone (синхронізується між пристроями). Повертає 204.

Запуск агентів

Це основна подія — виклик агента для обробки повідомлення.

Тіло запиту — підтримувані поля

Поле Обов'язково Опис
agentId так ID вбудованого режиму (наприклад, general) або ID користувацького агента
input.message так Текст повідомлення користувача
input.attachments ні Масив ID вкладень (вже завантажених через /v1/attachments) для додавання до цього кроку
input.variables ні Перевизначення змінних для конкретного запуску, що об'єднуються з резолвером змінних агента
input.tabContext ні Рядок довільної форми, що вставляється як контекст сторінки (використовується браузерним мостом)
input.messageId ні ID повідомлення, наданий клієнтом — корисно для дедуплікації при повторних спробах
threadId ні Існуючий тред для продовження. Якщо пропущено, створюється та повертається новий тред
mode ні "sync" або "async". За замовчуванням "async"

Синхронний режим

Очікування повної відповіді:

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

{
  "agentId": "general",
  "input": { "message": "What's the weather in Paris today?" },
  "mode": "sync"
}

Повертає 200 з { content, usage, status: "completed" } після завершення роботи агента. Якщо в роботі агента виникає помилка, повертає 500 з { error, status: "error" }. Синхронні запуски перериваються за таймаутом через 5 хвилин зі status: "error", якщо не отримано фінальної події — використовуйте async + SSE для завдань, що можуть тривати довше.

Асинхронний режим

Запустити та забути — корисно для тривалих завдань:

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

{
  "agentId": "my-research-agent",
  "input": { "message": "Write a 2000-word analysis of renewable energy trends" },
  "mode": "async"
}

Негайно повертає 202 з { runId, threadId, status: "running" }.

Опитування статусу:

GET /v1/runs/{runId}

Повертає { run: { runId, threadId, agentId, status, createdAt, content?, usage?, error? } }. Статус може бути одним із: running, completed, error або cancelled.

Стрімінг подій у реальному часі (SSE):

GET /v1/runs/{runId}/events

Повертає text/event-stream з кожною подією агента в міру їх виникнення: GENERATION_STARTED, STREAMING_CONTENT, виклики інструментів, активність субагентів та фінальна подія (GENERATION_COMPLETE, GENERATION_ERROR або GENERATION_CANCELLED).

Після фінальної події сервер надсилає останній SSE-фрейм з event: terminal та порожнім корисним навантаженням як явний маркер кінця потоку, після чого закриває з'єднання. Клієнти повинні розглядати отримання цього фрейму (або закриття з'єднання) як сигнал до припинення читання.

Якщо ви підписуєтеся після того, як запуск уже завершився, сервер відтворює один фрейм типу RUN_SNAPSHOT, що містить повний фінальний запис record, після чого йде маркер event: terminal, а потім з'єднання закривається.

Скасування запуску:

POST /v1/runs/{runId}/cancel

Повертає { run: { ..., status: "cancelled" } }.

Threads

Threads — це бесіди. Кожен запуск агента відбувається в межах thread, і вони зберігаються між сесіями. API дозволяє переглядати, читати, створювати та керувати threads програмно.

Список усіх threads (тільки метадані):

GET /v1/threads

Повертає { threads: [...] } для поточного профілю з видаленим масивом messages (використовуйте ендпоінт деталізації, коли вони вам потрібні). Усі інші поля зберігаються — id, title, createdAt, updatedAt, modeId, archived, статистика використання, а також subAgentHistories, anonymizerSnapshot, threadToolApprovals, threadVariables, threadToolOverrides, messagingBinding, scheduledTaskId, якщо вони встановлені. (Повний обсяг даних доступний виключно через API — трансляція бічної панелі через WebSocket використовує більш обмежений набір даних, щоб залишатися в межах лімітів передачі.)

Отримати thread з повним списком повідомлень:

GET /v1/threads/{id}

Повертає повний об'єкт thread, включаючи масив messages — кожне повідомлення користувача, відповідь асистента, виклик інструменту та результат роботи інструменту.

Отримати тільки повідомлення:

GET /v1/threads/{id}/messages

Повертає лише масив messages — це легше, ніж повний об'єкт thread, коли вам потрібна лише бесіда.

Створити thread:

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

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

Повертає 201 з об'єктом { thread }. Новий thread негайно з'являється на бічній панелі (через WebSocket трансляцію). API ніколи не перемикає активний thread у додатку під час створення — викличте PUT /v1/threads/active окремо, якщо вам це потрібно.

Оновити thread:

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

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

Поля, що підлягають оновленню: title, modeId, archived, lastUsedModel. Зміни транслюються на бічну панель у режимі реального часу.

Видалити thread:

DELETE /v1/threads/{id}

Виконує м'яке видалення thread (позначка для синхронізації). Повертає 204. Видалені threads переміщуються до кошика і можуть бути відновлені, доки кошик не буде очищено.

Активний thread:

GET /v1/threads/active            # Повертає { threadId }
PUT /v1/threads/active            # Тіло: { "threadId": "..." }

Керування кошиком:

GET /v1/threads/trash/count       # Повертає { count }
POST /v1/threads/trash/empty      # Повертає { deletedCount, protectedCount }

Захищені threads (збережені за допомогою перемикача зберігання даних) виключаються під час очищення кошика.

Продовження бесіди через API: Щоб надіслати наступне повідомлення в існуючий thread, використовуйте POST /v1/runs з ID цього thread:

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

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

Агент бачить повну історію бесіди з цього thread.

Вкладення

Вкладення — це файли, пов'язані з гілками обговорень: скріншоти, PDF, документи, завантажені зображення, згенеровані артефакти. API дозволяє переглядати, завантажувати, вивантажувати та керувати ними.

Список усіх вкладень (тільки метадані):

GET /v1/attachments

Повертає метадані вкладень для поточного профілю. Важкі поля (dataUrl, extractedContent, extractedImages) видаляються — використовуйте кінцеві точки деталей або контенту для їх отримання.

Список вкладень для конкретної гілки:

GET /v1/threads/{threadId}/attachments

Отримати метадані вкладення:

GET /v1/attachments/{id}

Повертає повні метадані, включаючи extractedContent (текст OCR, розібраний markdown), contentType, fileName, size та прапорець hasContent. Необроблені бінарні дані НЕ включаються — використовуйте для цього кінцеву точку /content.

Завантажити бінарний файл вкладення:

GET /v1/attachments/{id}/content

Повертає необроблений файл із правильними заголовками Content-Type та Content-Disposition. Спрямуйте це у файл:

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

Вивантажити вкладення:

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

{
  "threadId": "thread-id",
  "type": "user_upload",
  "contentType": "application/pdf",
  "fileName": "report.pdf",
  "description": "Квартальний звіт",
  "dataUrl": "data:application/pdf;base64,JVBERi0xLjQ..."
}

dataUrl — це URL-адреса даних у кодуванні base64. Повертає 201 з ID нового вкладення. Вкладення прив'язується до вказаної гілки.

Оновити метадані вкладення:

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

{ "description": "Оновлений опис", "fileName": "new-name.pdf" }

Видалити вкладення:

DELETE /v1/attachments/{id}

М'яке видалення через tombstone. Повертає 204.

MCP Сервери

Керуйте підключеннями до ваших MCP (Model Context Protocol) серверів — серверів, які надають агентам доступ до зовнішніх інструментів та джерел даних.

Список налаштованих серверів:

GET /v1/mcp-servers

Повертає всі конфігурації MCP серверів для поточного профілю. Чутливі поля (authToken, env, credentialId) видаляються з відповіді.

Отримати конфігурацію сервера:

GET /v1/mcp-servers/{id}

Додати новий 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"
}

Для віддалених HTTP серверів використовуйте "url" замість "command":

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

Дозволені необов'язкові поля для POST: command, args, env, url, description, transportType, authType, authToken, authHeader, headers, specType, specPath, timeoutMs, credentialId, oauthConnectionId, approval. Поля, що керуються сервером (customOAuth, hubPackageId, profileId, connectorId, teamPublished, teamOrgId, vectorClock, ...), не можуть бути встановлені через API.

Оновити сервер:

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

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

Поля, доступні для оновлення, відповідають білому списку POST (включаючи credentialId та oauthConnectionId — зручно для ротації OAuth підключення без видалення та повторного створення). Поля, що керуються сервером, залишаються лише для читання.

Увімкнути/вимкнути сервер:

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

{ "enabled": false }

Видалити сервер:

DELETE /v1/mcp-servers/{id}

Керування процесами

Для локальних (stdio) MCP серверів ви можете керувати процесом сервера безпосередньо.

Список запущених процесів:

GET /v1/mcp-servers/processes

Повертає запущені процеси серверів з pid, startedAt та статусом running.

Запустити сервер:

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

Зчитує command/args/env з конфігурації сервера та запускає процес. Повертає статус процесу.

Зупинити сервер:

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

Коректно завершує процес сервера (SIGTERM з переходом до SIGKILL у разі потреби).

Викликати метод JSON-RPC безпосередньо:

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

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

Надсилає прямий JSON-RPC 2.0 запит до сервера та повертає результат. Корисно для налагодження або виклику методів, які не доступні через API інструментів.

Інструменти та набори інструментів

Переглядайте та викликайте інструменти, якими користуються агенти, — вебперегляд, пошук, календар, Gmail, Slate та багато іншого.

Список наборів інструментів (згрупований):

GET /v1/toolkits

Повертає вбудовані інструменти, згруповані за категоріями (Productivity, Search, Utilities тощо), а також будь-які підключені сервери MCP як окремі набори інструментів, кожен із переліком власних дій.

Список усіх інструментів (плоский):

GET /v1/tools
GET /v1/tools?source=embedded   # Лише вбудовані інструменти
GET /v1/tools?source=mcp        # Лише інструменти серверів MCP

Отримати детальну інформацію про інструмент зі схемою вхідних даних:

GET /v1/tools/calculator

Повертає { tool: { name, displayName, description, source, category, inputSchema, actions?, requiredTier?, requiredRuntimes?, riskTier?, riskExplanation?, requiresApproval? } }.

Поле Значення
inputSchema JSON Schema для вхідних даних інструмента — перевіряйте перед викликом
actions Необов'язкові піддії (наприклад, read/write у Slate); кожна містить id, displayName, description, необов'язковий requiredTier та requiresApproval: true, якщо ця дія спочатку запитує підтвердження користувача (виклик через публічний API відхиляє її)
requiredTier Мінімальний рівень доступу користувача (free, якщо не вказано). Виклик через публічний API відхиляє будь-що вище за free
requiredRuntimes Платформи, на яких доступний цей інструмент (macos, ios тощо); якщо пропущено ⇒ скрізь
riskTier Рівень ризику згоди: low (за замовчуванням), medium, high
riskExplanation Зрозуміле для людини пояснення підвищеного riskTier
requiresApproval true, якщо інструмент потребує підтвердження користувача для кожного виклику — виклики через публічний API відхиляють такі інструменти

Прямий виклик інструмента:

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

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

Повертає { result }. Вхідні дані перевіряються на відповідність схемі інструмента — некоректні дані повертають 422 з подробицями, так само як і неправильно написана дія: назви мають бути точними (SEND_EMAIL — це не те саме, що send_email), виправлення не застосовуються. Передайте необов'язковий threadId, якщо інструменту потрібен контекст у межах треду (наприклад, пошук вкладень). Інструменту, який зберігає створений результат у розмові (генерація зображень, відео, музики та мовлення, python_run, зчитування зображень із GitHub), потрібен цей ідентифікатор: без threadId виклик відхиляється ще до того, як щось буде згенеровано або списано кошти. Результат зберігається в цій розмові під профілем, від імені якого надіслано запит, і ця розмова має належати цьому профілю (інакше — 403).

Обмеження доступу (Gating) — що відхиляє публічний API:

  • Інструменти, обмежені рівнем доступу (metadata.requiredTier !== 'free') → 403. Цикл агента перевіряє рівень доступу на основі сесії користувача; публічний API не переносить контекст рівня, тому консервативна політика полягає у відхиленні запиту. Замість цього використовуйте POST /v1/runs з агентом, який має відповідний рівень.
  • Інструменти, які вимагають підтвердження (metadata.approval.requiresApproval === true) → 403. У процесі немає людини (human in the loop), у якої можна було б запитати дозвіл. Викликайте через POST /v1/runs, що відображає запит користувачеві в додатку.
  • Для кожної ДІЇ (ACTION), після валідації вхідних даних — кожна помилка 403 вказує назву дії:
    • дія, яка в додатку спочатку запитала б користувача (перелічена в actionsRequiringApproval інструмента; actions[].requiresApproval у GET /v1/tools/:name). Дія, підтвердження якої залежить від її аргументів, відхиляється лише тоді, коли ці аргументи змусили б додаток запитати дозвіл — наприклад, create_event в agenda запитує дозвіл лише тоді, коли вона запрошує учасників, а ingest_document у web_browsing — лише тоді, коли завантажує документ на Google Drive (обидві є діями рівня Pro, тому на сьогодні публічний API у будь-якому разі відхиляє їх через їхній рівень);
    • дія, власний requiredTier якої вищий за free;
    • дія, вимкнена в Settings → Tool Configuration (вимкнення будь-якої назви з пари псевдонімів, наприклад send_email / send_message у mail, вимикає обидві).
  • Віддалені інструменти MCP → 501 з порадою використовувати /v1/runs (вони вимагають підпроцесу транспорту агента).

Інструменти комп'ютерного зору та роботи із зображеннями: спочатку завантажте файл через POST /v1/attachments, а потім передайте отриманий ідентифікатор вкладення всередині input (наприклад, { "input": { "attachment_id": "att_abc", "prompt": "What is in this image?" } }). Інструмент зчитує бінарні дані зі сховища за допомогою threadId; вам не потрібно передавати байти безпосередньо в тілі запиту.

Конектори

Керуйте інтеграціями OAuth — Google, Microsoft, GitHub, Notion, Slack та іншими.

Перегляд доступних інтеграцій:

GET /v1/connectors/catalog

Повертає всіх зареєстрованих провайдерів OAuth з їхніми іменами, категоріями та стандартними областями доступу (scopes).

Список ваших підключених акаунтів:

GET /v1/connectors

Повертає активні з'єднання для поточного профілю. Токени ніколи не розкриваються — лише метадані (провайдер, email, статус, області доступу, мітки часу).

Отримати одне з'єднання:

GET /v1/connectors/{id}

Повертає метадані для одного з'єднання. Токени ніколи не розкриваються.

Перевірити стан з'єднання:

POST /v1/connectors/{id}/test

Повертає { health: { status, isTokenExpired, canRefresh } }.

Видалити з'єднання:

DELETE /v1/connectors/{id}

Створення нових з'єднань вимагає інтерактивного процесу OAuth через інтерфейс додатка або маршрути /auth/*.

Тригери

Налаштовуйте агентів для автоматичного запуску — щоденні брифінги, щотижневі звіти, моніторинг через певні інтервали.

Кожен тригер має дискримінатор kind: schedule (за замовчуванням — спрацьовує за годинником), webhook (спрацьовує, коли зовнішній сервіс надсилає POST-запит на шлях вебхука) або messaging (спрацьовує від підключеного адаптера повідомлень — наприклад, вхідні повідомлення Slack/Discord, що відповідають фільтру каналу).

Список тригерів:

GET /v1/triggers

Повертає { triggers: [...] }. Кожен запис містить свій kind, розклад та поля, специфічні для типу (наприклад, webhookSecret/webhookPath для тригерів вебхуків, messagingAdapterId/messagingChannelFilter для тригерів повідомлень).

Отримати один тригер:

GET /v1/triggers/{id}

Створити запланований тригер:

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

{
  "name": "Ранковий брифінг",
  "prompt": "Підсумуй мої непрочитані електронні листи та сьогоднішній календар",
  "modeId": "general",
  "schedule": { "type": "daily", "time": "08:00" }
}

Підтримувані типи розкладів:

  • { "type": "interval", "minutes": 60 } — кожні N хвилин (мін. 15, макс. 1440)
  • { "type": "daily", "time": "09:00" } — щодня у вказаний час
  • { "type": "weekly", "day": "mon", "time": "09:00" } — щотижня
  • { "type": "weekdays", "time": "08:30" } — з понеділка по п'ятницю
  • { "type": "daysOfWeek", "days": ["mon", "wed", "fri"], "time": "10:00" } — у конкретні дні
  • { "type": "monthly", "dayOfMonth": 1, "time": "09:00" } — щомісяця
  • { "type": "manual" } — лише при запуску через API

Запустити тригер вручну:

POST /v1/triggers/{id}/fire

Повертає 202 з threadId для результату запуску.

Оновити або видалити:

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

Вебхуки

Тригери вебхуків дозволяють зовнішнім сервісам (CI/CD, моніторинг, конструктори форм) запускати агента через HTTP.

Створити тригер вебхука:

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

{
  "name": "Deploy hook",
  "prompt": "Відбулося розгортання: {{webhook.body}}",
  "modeId": "general",
  "kind": "webhook"
}

Повертає 201 з webhookSecret та webhookPath. Збережіть секрет — він знадобиться для підписання корисного навантаження.

Надіслати вебхук:

# Обчисліть HMAC-SHA256 необробленого тіла запиту
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"}

Кінцева точка вебхука НЕ потребує авторизації bearer — замість цього вона використовує перевірку HMAC. Повертає 202 з threadId запущеного процесу. Плейсхолдер {{webhook.body}} у запиті тригера замінюється необробленим тілом запиту.

Тригери повідомлень

Тригери повідомлень спрацьовують, коли підключений адаптер повідомлень (наприклад, інтеграція Slack або Discord, встановлена через Community Hub) отримує вхідне повідомлення, що відповідає фільтру тригера. Створюйте з kind: "messaging":

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

{
  "name": "Відповідач на згадки",
  "prompt": "Корисно дай відповідь на: {{message.text}}",
  "modeId": "general",
  "kind": "messaging",
  "messagingAdapterId": "slack-team-acme",
  "messagingChannelFilter": "#support"
}

Адаптер відповідає за відправку відповідних подій у тригер; messagingChannelFilter залежить від конкретного адаптера.

Користувацькі функції

Створюйте власні інструменти, які можуть викликати агенти. Функції пишуться на JavaScript або Python і виконуються в пісочниці.

Список функцій:

GET /v1/functions

Створити функцію:

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

{
  "name": "calculate_bmi",
  "description": "Розрахувати індекс маси тіла за зростом і вагою",
  "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 отримують input і повинні повернути результат. Функції Python встановлюють змінну result:

# Приклад на Python
result = {"bmi": round(input["weightKg"] / (input["heightM"] ** 2), 1)}

Виконати функцію безпосередньо:

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

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

Безпека: JavaScript працює в пісочниці Node vm (без доступу до файлової системи або мережі, таймаут 10с). Python працює як підпроцес із таймаутом 30с. Обидва варіанти перевіряють введення перед виконанням.

Оновити або видалити:

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

Навички

Навички — це збережені запити, на які агенти можуть посилатися та швидко запускати з вікна нової розмови. Навички, встановлені з Hub (керовані через встановлення пакетів), сюди НЕ входять — відображаються та редагуються лише навички, створені користувачем.

Список навичок:

GET /v1/skills

Повертає { skills: [...] } навичок, створених користувачем для активного профілю. Видалені навички, навички з Hub та тіні синхронізації відфільтровані.

Отримати одну навичку:

GET /v1/skills/{id}

Створити навичку:

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

{
  "prompt": "Підсумуй сторінку у 3 пунктах.",
  "tags": ["utility", "summarize"],
  "isFavorite": true,
  "modes": ["general"],
  "displayName": "Швидкий підсумок",
  "description": "Стислий огляд активної сторінки у трьох пунктах"
}

Обов'язковим є лише поле prompt. modes (необов'язково) обмежує навичку конкретними ID агентів; пропустіть для всіх режимів. Повертає 201 з новою навичкою (включаючи призначені сервером id, createdAt, updatedAt).

Оновити навичку:

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

{ "prompt": "Оновлений запит", "isFavorite": false }

Поля для оновлення: prompt, tags, modes, displayName, description, isFavorite. Спроби оновити навичку з Hub повертають 404.

Видалити навичку:

DELETE /v1/skills/{id}

М'яке видалення. Повертає 204. Для навичок з Hub повертає 404 — замість цього видаліть вихідний пакет.

Робочі процеси (Workflows)

Організовуйте роботу кількох агентів у DAG (спрямований ациклічний граф) — запускайте кроки паралельно, де це можливо, і передавайте результати попередніх кроків у наступні.

Валідація графа робочого процесу:

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

{
  "graph": {
    "nodes": [
      { "id": "research", "agentId": "general", "prompt": "Дослідити тенденції відновлюваної енергетики" },
      { "id": "analyze", "agentId": "general", "prompt": "Дослідити ціни конкурентів" },
      { "id": "report", "agentId": "general", "prompt": "Написати звіт, поєднавши: {{outputs.research}} та {{outputs.analyze}}", "dependsOn": ["research", "analyze"] }
    ]
  }
}

Повертає { valid: true/false, errors: [...] }. Перевіряє наявність циклів, дублікатів ID та відсутніх посилань на залежності.

Виконати робочий процес:

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

{
  "graph": {
    "nodes": [
      { "id": "research", "agentId": "general", "prompt": "Дослідити тенденції відновлюваної енергетики" },
      { "id": "summarize", "agentId": "general", "prompt": "Підсумувати: {{outputs.research}}", "dependsOn": ["research"] }
    ]
  }
}

Повертає { status: "completed", outputs: { research: "...", summarize: "..." }, nodeResults: {...} }.

Незалежні вузли (без спільних залежностей) виконуються паралельно. Плейсхолдер {{outputs.nodeId}} у промпті вузла замінюється на вихідний контент названого вищестоящого вузла. Кожен вузол — це повноцінний запуск агента, тому він може використовувати інструменти, переглядати веб-сторінки та мати доступ до всіх можливостей цільового агента.

Бази знань

Організовуйте документи в колекції з можливістю пошуку, на які можуть посилатися агенти.

Список баз знань:

GET /v1/knowledge/bases

Створити базу знань:

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

{ "name": "Дослідницькі роботи" }

Повертає 201 з ID нової бази.

Завантажити документ у базу знань:

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

{
  "fileName": "research-paper.pdf",
  "contentType": "application/pdf",
  "dataUrl": "data:application/pdf;base64,JVBERi0xLjQ...",
  "description": "Тенденції відновлюваної енергетики 2026"
}

Поле dataUrl — це URL-адреса даних у кодуванні base64. Повертає 201 з метаданими документа.

Список документів у базі знань:

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

Пошук у базі знань:

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

{ "query": "відновлювана енергетика" }

Повертає відповідні документи на основі імені файлу та опису. Семантичний (векторний) пошук з'явиться в майбутніх версіях.

Видалити документ або базу знань:

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

Експорт та імпорт агентів

Діліться агентами як портативними пакетами — між пристроями, командами або через Community Hub.

Експортувати агента:

POST /v1/agents/{id}/export

Повертає пакет JSON, що містить визначення агента, вимоги до інструментів (на основі увімкнених інструментів), вимоги до конекторів (які постачальники OAuth потрібні) та шаблони тригерів. Метадані синхронізації видаляються — пакет є чистим, автономним кресленням.

Імпортувати агента:

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

{
  \"package\": {
    \"$schema\": \"caiioo.agent.package/v1\",
    \"agent\": {
      \"id\": \"shared-research-agent\",
      \"branding\": { \"name\": \"Research Agent\", \"description\": \"Від команди\" },
      \"defaultSettings\": { \"systemPrompt\": \"Ви досліджуєте речі.\" },
      \"settingLevels\": {}
    },
    \"toolRequirements\": [
      { \"toolId\": \"web_browsing\", \"enabled\": true },
      { \"toolId\": \"search_tools\", \"enabled\": true }
    ]
  }
}

Повертає 201 з інстальованим агентом. Конфлікти ID з вбудованими або існуючими агентами повертають 409.

Обробка помилок

API використовує стандартні коди стану HTTP:

Код Значення
200 Успішно
201 Створено
202 Прийнято (асинхронна операція розпочата)
204 Видалено (немає вмісту)
400 Неправильний запит — перевірте поле error для деталей
401 Неавторизовано — відсутній або недійсний секрет сесії
403 Заборонено — наприклад, спроба змінити вбудованого агента
404 Не знайдено
409 Конфлікт — наприклад, ID агента вже існує
422 Помилка валідації — вхідні дані не відповідають схемі інструменту
429 Обмеження частоти запитів — див. ліміти в розділі Автентифікація
500 Помилка сервера — перевірте поле error
501 Не реалізовано — функція існує, але недоступна цим способом
503 Сервіс недоступний — сховище або провайдер не готові

Усі відповіді з помилками містять { "error": "людиночитане повідомлення" }.

Приклад швидкого старту

Ось повний робочий процес: створення агента, його запуск та стрімінг результатів.

# 1. Створення користувацького агента
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": "Стисло підсумуй будь-яке введення у 3 пунктах.",
      "enabledTools": { "web_browsing": true }
    },
    "settingLevels": {}
  }'

# 2. Асинхронний запуск
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\": \"Підсумуй https://en.wikipedia.org/wiki/Artificial_intelligence\" }, \"mode\": \"async\" }")

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

# 3. Стрімінг подій
curl -N http://localhost:3847/v1/runs/$RUN_ID/events \
  -H "Authorization: Bearer $API_TOKEN"

# 4. Експорт агента для спільного використання
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.