Ini adalah terjemahan mesin dari dokumen asli berbahasa Inggris. Jika terjadi perbedaan antara terjemahan ini dan versi asli bahasa Inggris, maka versi bahasa Inggris yang akan berlaku. Baca versi asli bahasa Inggris


API Publik

Caiioo menyertakan API REST yang memungkinkan Anda mengontrol semuanya secara terprogram: menjalankan agen, mengelola alat, menjadwalkan tugas, dan banyak lagi. API ini berada di server lokal yang sama yang mendukung aplikasi desktop dan bridge browser.

URL Dasar: http://localhost:3847/v1

Autentikasi: Dua cara untuk mengautentikasi, keduanya dibatasi oleh sakelar API di pengaturan:

Untuk konsumen eksternal (skrip, integrasi, curl): Atur token akses API di Pengaturan > Akses API, lalu gunakan sebagai token Bearer:

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

Untuk aplikasi lokal (otomatis): Aplikasi desktop Caiioo, ekstensi browser, dan aplikasi seluler mengautentikasi secara otomatis melalui header autentikasi relay yang ada (x-relay-auth; header HTTP tidak peka huruf besar-kecil). Tidak perlu penyiapan manual — aplikasi menangani ini di balik layar. Permintaan relay-auth melewati sakelar Aktifkan API Publik karena sudah dipercaya; hanya permintaan token bearer yang dibatasi oleh sakelar tersebut.

Penyiapan:

  1. Buka Pengaturan Caiioo > Akses API
  2. Aktifkan Aktifkan API Publik
  3. Atur Token akses API (string apa pun yang Anda pilih — perlakukan seperti kata sandi)
  4. Gunakan token tersebut di semua permintaan API

API tersedia di localhost dan melalui relay pribadi. Periksa GET /v1/auth/info (tidak perlu autentikasi) untuk status saat ini dan instruksi penyiapan.

Batas kecepatan: setiap permintaan /v1/* dibatasi kecepatannya per IP klien — 100 permintaan GET per menit untuk pembacaan dan 30 permintaan tulis per menit (POST / PATCH / DELETE) gabungan. Permintaan yang melebihi batas akan mendapatkan 429. Pengiriman webhook (POST /v1/webhooks/:id) tidak diautentikasi dengan bearer dan tidak tunduk pada batas ini.

Profil

Satu perangkat dapat menampung beberapa profil pengguna (misalnya pribadi + kerja). API memungkinkan skrip eksternal memeriksa profil yang tersedia dan beralih ke profil aktif sebelum melakukan pekerjaan lain. Pembuatan, pembaruan, dan penghapusan profil sengaja tidak diekspos melalui API publik — alur tersebut termasuk dalam UI orientasi aplikasi.

Daftar profil:

GET /v1/profiles

Mengembalikan { profiles: [...] } dengan satu entri per profil yang tidak dihapus. Setiap entri mencakup id, name, email, avatarUrl, tier, accessibleModes, license, organization, preferences, onboardingComplete, createdAt, lastAccessedAt. Bidang yang mengandung token (serviceCredentials, oauthConnections) dan internal sinkronisasi (vectorClock, lastModifiedBy) dihapus. Gunakan /v1/connectors untuk memeriksa koneksi OAuth.

Dapatkan profil aktif:

GET /v1/profiles/active

Mengembalikan { profile } untuk profil yang saat ini digunakan oleh server ini. Semua sumber daya /v1/* yang dicakup ke profil (utas, lampiran, pengaturan, keahlian) beroperasi terhadap profil ini.

Ganti profil aktif:

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

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

Mengembalikan { profile } untuk profil yang baru aktif. Mengembalikan 404 jika ID bukan profil yang dikenal.

Providers & Models

Temukan penyedia LLM mana saja yang telah dikonfigurasi dan model apa saja yang tersedia.

Daftar penyedia:

GET /v1/providers

Mengembalikan setiap tipe penyedia yang didukung. Saat ini: anthropic, openai, google, openrouter, ollama, poe, mlx, perplexity, baseten, cloudflare. Setiap entri mencakup type, displayName, icon, requiresApiKey, hasApiKey, dan objek capabilities dengan flag di bawah ini.

Flag Kapabilitas Arti
supportsVision Penyedia dapat menerima input gambar
supportsPdfFile Penyedia dapat menerima blok konten file PDF mentah secara native
supportsToolCalling Penyedia mendukung pemanggilan fungsi/alat (tool calling)
supportsStreaming Penyedia mengirimkan token secara bertahap (streaming)
supportsExtendedThinking Penyedia mengekspos anggaran penalaran/pemikiran (reasoning/thinking budget)
supportsPromptCaching Penyedia mendukung direktif prompt-cache
nativeReasoningBlocks Penyedia memancarkan pemikiran sebagai blok pesan native (bukan teks)
requiresThoughtSignature Penyedia memerlukan token pemikiran bertanda tangan untuk dikirimkan kembali

Flag kapabilitas mencerminkan bidang readonly capabilities dari setiap kelas penyedia (lihat src/shared/providers/*-provider.ts) dan divalidasi oleh pengujian drift sentinel — panggil endpoint ini saat runtime daripada melakukan hardcoding pada matriks.

Catatan untuk penyedia BYOK:

  • perplexity mengekspos daftar model Sonar yang dikurasi (Perplexity tidak memiliki endpoint publik /models).
  • cloudflare (AI Gateway) adalah BYOK + multi-vendor; daftar model ditentukan oleh konfigurasi gateway Anda dan dikembalikan sebagai array kosong oleh /v1/providers/cloudflare/models. Gunakan katalog gateway Anda sendiri.

Daftar model untuk penyedia tertentu:

GET /v1/providers/openrouter/models

Mengembalikan katalog model untuk penyedia tersebut. Setiap model mencakup id, displayName, dan contextLength jika tersedia. Mengembalikan 503 ketika penyedia tidak memiliki API key atau katalog upstream-nya tidak dapat dijangkau.

Katalog gabungan di seluruh penyedia:

GET /v1/models

Menggabungkan model dari setiap penyedia yang dikonfigurasi ke dalam satu daftar. Penyedia tanpa API key akan dilewati dan dicantumkan dalam warnings.

Agen

Agen adalah inti dari caiioo. Setiap agen adalah sebuah Mode — kepribadian yang dikonfigurasi dengan perintah sistem, alat, variabel, dan keahliannya sendiri.

Daftar semua agen:

GET /v1/agents

Mengembalikan agen bawaan (Belanja, Tempat Kerja, Umum) dan agen kustom apa pun yang telah Anda buat. Masing-masing ditandai dengan source: \"builtin\" atau source: \"custom\".

Buat agen kustom:

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

{
  \"id\": \"my-research-agent\",
  \"branding\": {
    \"name\": \"Agen Riset\",
    \"description\": \"Mencari di web dan merangkum temuan\"
  },
  \"defaultSettings\": {
    \"systemPrompt\": \"Anda adalah asisten riset. Selalu kutip sumber.\",
    \"enabledTools\": { \"web_browsing\": true, \"search_tools\": true }
  },
  \"settingLevels\": {}
}

Mengembalikan 201 dengan agen yang dibuat. Jam vektor dilampirkan secara otomatis untuk sinkronisasi.

Perbarui agen:

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

{ \"branding\": { \"name\": \"Agen Riset\", \"description\": \"Deskripsi yang diperbarui\" } }

Menggabungkan patch ke dalam agen yang ada dan meningkatkan jam vektor. Agen bawaan mengembalikan 403 — mereka bersifat baca-saja.

Hapus agen:

DELETE /v1/agents/my-research-agent

Penghapusan lunak melalui tombstone (sinkron di seluruh perangkat). Mengembalikan 204.

Menjalankan Agen

Ini adalah acara utama — memanggil agen untuk memproses pesan.

Request body — bidang yang didukung

Bidang Wajib Deskripsi
agentId ya ID mode bawaan (misalnya general) atau ID agen kustom
input.message ya Teks pesan pengguna
input.attachments tidak Array ID lampiran (yang sudah diunggah melalui /v1/attachments) untuk dilampirkan pada giliran ini
input.variables tidak Penggantian variabel per-eksekusi yang digabungkan ke dalam penyelesai variabel agen
input.tabContext tidak String bentuk bebas yang disuntikkan sebagai konteks halaman (digunakan oleh browser bridge)
input.messageId tidak ID pesan yang disediakan klien — berguna untuk deduplikasi jika Anda mencoba lagi
threadId tidak Thread yang sudah ada untuk dilanjutkan. Jika dikosongkan, thread baru akan dibuat dan dikembalikan
mode tidak "sync" atau "async". Default-nya adalah "async"

Mode Sinkron (Synchronous)

Tunggu respons lengkap:

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

{
  "agentId": "general",
  "input": { "message": "Bagaimana cuaca di Paris hari ini?" },
  "mode": "sync"
}

Mengembalikan 200 dengan { content, usage, status: "completed" } setelah agen selesai. Jika agen mengalami kesalahan, mengembalikan 500 dengan { error, status: "error" }. Eksekusi sinkron akan habis waktu (time out) setelah 5 menit dengan status: "error" jika tidak ada aktivitas terminal yang diterima — gunakan async + SSE untuk apa pun yang mungkin memakan waktu lebih lama.

Mode Asinkron (Asynchronous)

Kirim dan lupakan — berguna untuk tugas yang memakan waktu lama:

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

{
  "agentId": "my-research-agent",
  "input": { "message": "Tulis analisis 2000 kata tentang tren energi terbarukan" },
  "mode": "async"
}

Mengembalikan 202 segera dengan { runId, threadId, status: "running" }.

Polling untuk status:

GET /v1/runs/{runId}

Mengembalikan { run: { runId, threadId, agentId, status, createdAt, content?, usage?, error? } }. Status adalah salah satu dari running, completed, error, atau cancelled.

Streaming aktivitas secara real-time (SSE):

GET /v1/runs/{runId}/events

Mengembalikan text/event-stream dengan setiap aktivitas agen saat terjadi: GENERATION_STARTED, STREAMING_CONTENT, pemanggilan alat (tool calls), aktivitas sub-agen, dan aktivitas terminal (GENERATION_COMPLETE, GENERATION_ERROR, atau GENERATION_CANCELLED).

Setelah aktivitas terminal, server memancarkan satu frame SSE terakhir dengan event: terminal dan payload data kosong sebagai penanda akhir aliran (end-of-stream) yang eksplisit, lalu menutup koneksi. Klien harus menganggap penerimaan frame tersebut (atau penutupan koneksi) sebagai sinyal untuk berhenti membaca.

Jika Anda berlangganan setelah eksekusi selesai, server memutar ulang satu frame bertipe RUN_SNAPSHOT yang berisi record final lengkap, diikuti oleh penanda event: terminal, lalu ditutup.

Membatalkan eksekusi:

POST /v1/runs/{runId}/cancel

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

Threads

Threads adalah percakapan. Setiap eksekusi agen terjadi di dalam sebuah thread, dan threads tetap ada di berbagai sesi. API memungkinkan Anda untuk mencantumkan, membaca, membuat, dan mengelola threads secara terprogram.

Daftar semua threads (hanya metadata):

GET /v1/threads

Mengembalikan { threads: [...] } untuk profil saat ini dengan messages yang dihilangkan (gunakan endpoint detail saat Anda membutuhkannya). Setiap bidang lainnya dipertahankan — id, title, createdAt, updatedAt, modeId, archived, statistik penggunaan, ditambah subAgentHistories, anonymizerSnapshot, threadToolApprovals, threadVariables, threadToolOverrides, messagingBinding, scheduledTaskId jika diatur. (Payload yang lebih kaya ini eksklusif untuk API — siaran sidebar WebSocket menggunakan pemotongan yang lebih ketat agar tetap di bawah batas transportasi.)

Dapatkan thread dengan pesan lengkap:

GET /v1/threads/{id}

Mengembalikan thread lengkap termasuk array messages — setiap pesan pengguna, respons asisten, panggilan tool, dan hasil tool.

Dapatkan hanya pesan:

GET /v1/threads/{id}/messages

Mengembalikan hanya array messages — lebih ringan daripada objek thread lengkap saat Anda hanya membutuhkan percakapan tersebut.

Buat sebuah thread:

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

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

Mengembalikan 201 dengan { thread }. Thread baru akan muncul di sidebar segera (melalui siaran WebSocket). API tidak pernah mengalihkan thread aktif aplikasi saat pembuatan — panggil PUT /v1/threads/active secara terpisah jika Anda menginginkannya.

Perbarui sebuah thread:

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

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

Bidang yang dapat diperbarui: title, modeId, archived, lastUsedModel. Perubahan disiarkan ke sidebar secara real-time.

Hapus sebuah thread:

DELETE /v1/threads/{id}

Menghapus thread secara lunak (tombstone untuk sinkronisasi). Mengembalikan 204. Thread yang dihapus pindah ke tempat sampah dan dapat dipulihkan hingga tempat sampah dikosongkan.

Thread aktif:

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

Manajemen tempat sampah:

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

Threads yang dilindungi (dipertahankan melalui toggle retensi data) dikecualikan dari pengosongan tempat sampah.

Melanjutkan percakapan melalui API: Untuk mengirim pesan tindak lanjut ke thread yang sudah ada, gunakan POST /v1/runs dengan 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"
}

Agen akan melihat seluruh riwayat percakapan dari thread tersebut.

Lampiran

Lampiran adalah file yang ditautkan ke thread — tangkapan layar, PDF, dokumen, gambar yang diunggah, artefak yang dihasilkan. API memungkinkan Anda mencantumkan, mengunggah, mengunduh, dan mengelolanya.

Daftar semua lampiran (hanya metadata):

GET /v1/attachments

Mengembalikan metadata lampiran untuk profil saat ini. Bidang yang berat (dataUrl, extractedContent, extractedImages) dihapus — gunakan endpoint detail atau konten untuk itu.

Daftar lampiran untuk thread tertentu:

GET /v1/threads/{threadId}/attachments

Dapatkan metadata lampiran:

GET /v1/attachments/{id}

Mengembalikan metadata lengkap termasuk extractedContent (teks OCR, markdown yang diparsing), contentType, fileName, size, dan flag hasContent. Biner mentah TIDAK disertakan — gunakan endpoint /content untuk itu.

Unduh biner lampiran:

GET /v1/attachments/{id}/content

Mengembalikan file mentah dengan header Content-Type dan Content-Disposition yang benar. Alirkan ini ke sebuah file:

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

Unggah lampiran:

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

{
  "threadId": "thread-id",
  "type": "user_upload",
  "contentType": "application/pdf",
  "fileName": "laporan.pdf",
  "description": "Laporan kuartalan",
  "dataUrl": "data:application/pdf;base64,JVBERi0xLjQ..."
}

dataUrl adalah URL data yang dikodekan base64. Mengembalikan 201 dengan ID lampiran baru. Lampiran ditautkan ke thread yang ditentukan.

Perbarui metadata lampiran:

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

{ "description": "Deskripsi yang diperbarui", "fileName": "nama-baru.pdf" }

Hapus lampiran:

DELETE /v1/attachments/{id}

Penghapusan lunak melalui tombstone. Mengembalikan 204.

Server MCP

Kelola koneksi server MCP (Model Context Protocol) Anda — server yang memberikan akses kepada agen ke alat eksternal dan sumber data.

Daftar server yang dikonfigurasi:

GET /v1/mcp-servers

Mengembalikan semua konfigurasi server MCP untuk profil saat ini. Bidang sensitif (authToken, env, credentialId) dihapus dari respons.

Dapatkan konfigurasi server:

GET /v1/mcp-servers/{id}

Tambah server MCP baru:

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

Untuk server HTTP jarak jauh, gunakan "url" alih-alih "command":

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

Bidang opsional yang diterima pada POST: command, args, env, url, description, transportType, authType, authToken, authHeader, headers, specType, specPath, timeoutMs, credentialId, oauthConnectionId, approval. Bidang yang dikelola server (customOAuth, hubPackageId, profileId, connectorId, teamPublished, teamOrgId, vectorClock, ...) tidak dapat diatur melalui API.

Perbarui server:

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

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

Bidang yang dapat di-patch mencerminkan daftar izin POST (termasuk credentialId dan oauthConnectionId — berguna untuk merotasi koneksi OAuth tanpa hapus-dan-buat-ulang). Bidang yang dikelola server tetap bersifat baca-saja (read-only).

Aktifkan/nonaktifkan server:

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

{ "enabled": false }

Hapus server:

DELETE /v1/mcp-servers/{id}

Manajemen Proses

Untuk server MCP lokal (stdio), Anda dapat mengelola proses server secara langsung.

Daftar proses yang sedang berjalan:

GET /v1/mcp-servers/processes

Mengembalikan proses server yang sedang berjalan dengan status pid, startedAt, dan running.

Mulai server:

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

Membaca command/args/env dari konfigurasi server dan menjalankan prosesnya. Mengembalikan status proses.

Hentikan server:

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

Menghentikan proses server secara halus (SIGTERM dengan fallback ke SIGKILL).

Panggil metode JSON-RPC secara langsung:

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

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

Mengirimkan permintaan mentah JSON-RPC 2.0 ke server dan mengembalikan hasilnya. Berguna untuk debugging atau memanggil metode yang tidak diekspos melalui API tools.

Tools & Toolkits

Telusuri dan panggil alat (tools) yang digunakan agen — penjelajahan web, pencarian, kalender, Gmail, Slate, dan banyak lagi.

Daftar toolkit (dikelompokkan):

GET /v1/toolkits

Mengembalikan alat yang tertanam (embedded tools) yang dikelompokkan berdasarkan kategori (Produktivitas, Pencarian, Utilitas, dll.) dan server MCP apa pun yang terhubung sebagai toolkit terpisah, masing-masing dengan daftar tindakannya.

Daftar semua alat (flat):

GET /v1/tools
GET /v1/tools?source=embedded   # Hanya alat bawaan
GET /v1/tools?source=mcp        # Hanya alat server MCP

Dapatkan detail alat dengan skema input:

GET /v1/tools/calculator

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

Bidang Arti
inputSchema JSON Schema untuk input alat — validasi sebelum memanggil
actions Sub-tindakan opsional (misalnya Slate read/write); masing-masing memiliki id, displayName, description, requiredTier opsional
requiredTier Tingkat pengguna minimum (free jika diabaikan). Pemanggilan API publik menolak apa pun di atas free
requiredRuntimes Platform tempat alat ini tersedia (macos, ios, dll.); abaikan ⇒ tersedia di mana saja
riskTier Risiko persetujuan: low (default), medium, high
riskExplanation Alasan yang dapat dibaca manusia mengapa riskTier ditingkatkan
requiresApproval true ketika alat memerlukan persetujuan pengguna per panggilan — pemanggilan API publik menolak ini

Panggil alat secara langsung:

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

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

Mengembalikan { result }. Input divalidasi terhadap skema alat — input yang tidak valid mengembalikan 422 dengan detail. Sertakan threadId opsional jika alat memerlukan konteks lingkup-utas (misalnya pencarian lampiran).

Gating — apa yang ditolak oleh API publik:

  • Alat dengan pembatasan tingkat (metadata.requiredTier !== 'free') → 403. Loop agen memeriksa tingkat terhadap sesi pengguna; API publik tidak membawa konteks tingkat, sehingga kebijakan konservatifnya adalah menolak. Gunakan POST /v1/runs dengan agen yang memiliki tingkat yang tepat sebagai gantinya.
  • Alat yang memerlukan persetujuan (metadata.approval.requiresApproval === true) → 403. Tidak ada manusia dalam loop untuk dimintai persetujuan. Panggil melalui POST /v1/runs (yang memunculkan perintah kepada pengguna) atau atur mode persetujuan alat ke approve_all di aplikasi untuk melewati ini.
  • Alat MCP jarak jauh501 dengan panduan untuk menggunakan /v1/runs (alat ini memerlukan transport subproses agen).

Alat visi dan penggunaan gambar: unggah melalui POST /v1/attachments terlebih dahulu, lalu teruskan ID lampiran yang dikembalikan di dalam input (misalnya { "input": { "attachment_id": "att_abc", "prompt": "Apa yang ada di gambar ini?" } }). Alat tersebut membaca biner dari penyimpanan melalui threadId; Anda tidak meneruskan byte secara inline.

Konektor

Kelola integrasi OAuth — Google, Microsoft, GitHub, Notion, Slack, dan lainnya.

Jelajahi integrasi yang tersedia:

GET /v1/connectors/catalog

Mengembalikan semua penyedia OAuth yang terdaftar beserta nama, kategori, dan cakupan defaultnya.

Daftar akun Anda yang terhubung:

GET /v1/connectors

Mengembalikan koneksi aktif untuk profil saat ini. Token tidak pernah diekspos — hanya metadata (penyedia, email, status, cakupan, stempel waktu).

Dapatkan satu koneksi:

GET /v1/connectors/{id}

Mengembalikan metadata untuk satu koneksi (penyedia, email, status, cakupan, stempel waktu). Token tidak pernah diekspos.

Periksa kesehatan koneksi:

POST /v1/connectors/{id}/test

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

Hapus koneksi:

DELETE /v1/connectors/{id}

Membuat koneksi baru memerlukan alur OAuth interaktif melalui UI aplikasi atau rute /auth/*.

Pemicu

Jadwalkan agen untuk berjalan secara otomatis — pengarahan harian, laporan mingguan, pemantauan berbasis interval.

Setiap pemicu memiliki diskriminator kind: schedule (default — berjalan berdasarkan jam), webhook (berjalan saat layanan eksternal melakukan POST ke jalur webhook), atau messaging (berjalan dari adaptor pesan yang terhubung — mis. pesan Slack/Discord masuk yang sesuai dengan filter saluran).

Daftar pemicu:

GET /v1/triggers

Mengembalikan { triggers: [...] }. Setiap entri menyertakan kind, jadwal, dan bidang khusus jenis (mis. webhookSecret/webhookPath untuk pemicu webhook, messagingAdapterId/messagingChannelFilter untuk pemicu pesan).

Dapatkan satu pemicu:

GET /v1/triggers/{id}

Buat pemicu terjadwal:

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

{
  \"name\": \"Morning Briefing\",
  \"prompt\": \"Ringkas email saya yang belum dibaca dan kalender hari ini\",
  \"modeId\": \"general\",
  \"schedule\": { \"type\": \"daily\", \"time\": \"08:00\" }
}

Tipe jadwal yang didukung:

  • { \"type\": \"interval\", \"minutes\": 60 } — setiap N menit (min 15, max 1440)
  • { \"type\": \"daily\", \"time\": \"09:00\" } — setiap hari pada waktu tertentu
  • { \"type\": \"weekly\", \"day\": \"mon\", \"time\": \"09:00\" } — mingguan
  • { \"type\": \"weekdays\", \"time\": \"08:30\" } — Senin sampai Jumat
  • { \"type\": \"daysOfWeek\", \"days\": [\"mon\", \"wed\", \"fri\"], \"time\": \"10:00\" } — hari tertentu
  • { \"type\": \"monthly\", \"dayOfMonth\": 1, \"time\": \"09:00\" } — bulanan
  • { \"type\": \"manual\" } — hanya saat dijalankan melalui API

Jalankan pemicu secara manual:

POST /v1/triggers/{id}/fire

Mengembalikan 202 dengan threadId untuk proses yang dihasilkan.

Perbarui atau hapus:

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

Webhook

Pemicu webhook memungkinkan layanan eksternal (CI/CD, pemantauan, pembuat formulir) memicu jalannya agen melalui HTTP.

Buat pemicu webhook:

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

{
  \"name\": \"Deploy hook\",
  \"prompt\": \"Sebuah deploy terjadi: {{webhook.body}}\",
  \"modeId\": \"general\",
  \"kind\": \"webhook\"
}

Mengembalikan 201 dengan webhookSecret dan webhookPath. Simpan rahasia tersebut — Anda akan membutuhkannya untuk menandatangani payload.

Kirim webhook:

# Hitung HMAC-SHA256 dari body permintaan mentah
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 webhook TIDAK memerlukan autentikasi bearer — ia menggunakan verifikasi HMAC sebagai gantinya. Mengembalikan 202 dengan threadId dari proses yang dikirim. Placeholder {{webhook.body}} dalam prompt pemicu diganti dengan body permintaan mentah.

Pemicu pesan

Pemicu pesan berjalan saat adaptor pesan yang terhubung (mis. integrasi Slack atau Discord yang diinstal melalui Community Hub) menerima pesan masuk yang sesuai dengan filter pemicu. Buat dengan kind: \"messaging\":

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

{
  \"name\": \"Mention responder\",
  \"prompt\": \"Balas dengan membantu ke: {{message.text}}\",
  \"modeId\": \"general\",
  \"kind\": \"messaging\",
  \"messagingAdapterId\": \"slack-team-acme\",
  \"messagingChannelFilter\": \"#support\"
}

Adaptor bertanggung jawab untuk mengirimkan peristiwa yang cocok ke pemicu; messagingChannelFilter bersifat spesifik untuk adaptor.

Fungsi Kustom

Buat alat Anda sendiri yang dapat dipanggil oleh agen. Fungsi ditulis dalam JavaScript atau Python dan dieksekusi dalam sandbox.

Daftar fungsi:

GET /v1/functions

Buat fungsi:

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

{
  "name": "hitung_bmi",
  "description": "Hitung Indeks Massa Tubuh dari tinggi dan berat badan",
  "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"]
  }
}

Fungsi JavaScript menerima input dan harus mengembalikan hasil. Fungsi Python menetapkan variabel result:

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

Eksekusi fungsi secara langsung:

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

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

Keamanan: JavaScript berjalan di sandbox vm Node (tanpa akses sistem berkas atau jaringan, batas waktu 10 detik). Python berjalan sebagai subproses dengan batas waktu 30 detik. Keduanya memvalidasi input sebelum eksekusi.

Perbarui atau hapus:

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

Keahlian

Keahlian adalah perintah tersimpan yang dapat dirujuk oleh agen dan diluncurkan dengan cepat dari tampilan percakapan kosong. Keahlian yang diinstal melalui Hub (dikelola melalui instalasi paket) TIDAK disertakan di sini — hanya keahlian buatan pengguna yang terdaftar dan dapat diedit.

Daftar keahlian:

GET /v1/skills

Mengembalikan { skills: [...] } dari keahlian buatan pengguna untuk profil aktif. Keahlian yang dihapus (tombstoned), overlay hub, dan bayangan sinkronisasi difilter.

Dapatkan satu keahlian:

GET /v1/skills/{id}

Buat keahlian:

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

{
  "prompt": "Ringkas halaman ini dalam 3 poin.",
  "tags": ["utilitas", "ringkas"],
  "isFavorite": true,
  "modes": ["general"],
  "displayName": "Ringkasan Cepat",
  "description": "TL;DR tiga poin dari halaman aktif"
}

Hanya prompt yang diperlukan. modes (opsional) membatasi keahlian ke ID agen tertentu; kosongkan untuk semua mode. Mengembalikan 201 dengan keahlian baru (termasuk id, createdAt, updatedAt yang ditetapkan server).

Perbarui keahlian:

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

{ "prompt": "Perintah yang diperbarui", "isFavorite": false }

Bidang yang dapat diubah: prompt, tags, modes, displayName, description, isFavorite. Upaya untuk mengubah keahlian overlay hub mengembalikan 404.

Hapus keahlian:

DELETE /v1/skills/{id}

Penghapusan lunak melalui tombstone. Mengembalikan 204. Keahlian overlay hub mengembalikan 404 — hapus paket sumber sebagai gantinya.

Alur Kerja

Atur beberapa agen dalam DAG (directed acyclic graph) — jalankan langkah-langkah secara paralel jika memungkinkan, dan masukkan hasil dari langkah sebelumnya ke langkah berikutnya.

Validasi grafik alur kerja:

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

{
  "graph": {
    "nodes": [
      { "id": "research", "agentId": "general", "prompt": "Riset tren energi terbarukan" },
      { "id": "analyze", "agentId": "general", "prompt": "Riset harga kompetitor" },
      { "id": "report", "agentId": "general", "prompt": "Tulis laporan yang menggabungkan: {{outputs.research}} dan {{outputs.analyze}}", "dependsOn": ["research", "analyze"] }
    ]
  }
}

Mengembalikan { valid: true/false, errors: [...] }. Memeriksa adanya siklus, ID duplikat, dan referensi dependensi yang hilang.

Eksekusi alur kerja:

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

{
  "graph": {
    "nodes": [
      { "id": "research", "agentId": "general", "prompt": "Riset tren energi terbarukan" },
      { "id": "summarize", "agentId": "general", "prompt": "Ringkas: {{outputs.research}}", "dependsOn": ["research"] }
    ]
  }
}

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

Node independen (tanpa dependensi bersama) berjalan secara paralel. Placeholder {{outputs.nodeId}} dalam prompt node diganti dengan konten keluaran dari node hulu yang disebutkan. Setiap node adalah eksekusi agen penuh, sehingga dapat menggunakan alat, menjelajahi web, dan mengakses semua kemampuan agen target.

Basis Pengetahuan

Atur dokumen ke dalam koleksi yang dapat dicari yang dapat dirujuk oleh agen.

Daftar basis pengetahuan:

GET /v1/knowledge/bases

Buat basis pengetahuan:

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

{ "name": "Makalah Riset" }

Mengembalikan 201 dengan ID basis baru.

Unggah dokumen ke basis pengetahuan:

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

{
  "fileName": "makalah-riset.pdf",
  "contentType": "application/pdf",
  "dataUrl": "data:application/pdf;base64,JVBERi0xLjQ...",
  "description": "Tren energi terbarukan 2026"
}

Bidang dataUrl adalah URL data yang dikodekan base64. Mengembalikan 201 dengan metadata dokumen.

Daftar dokumen dalam basis pengetahuan:

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

Cari di dalam basis pengetahuan:

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

{ "query": "energi terbarukan" }

Mengembalikan dokumen yang cocok berdasarkan nama file dan deskripsi. Pencarian semantik (vektor) akan hadir dalam rilis mendatang.

Hapus dokumen atau basis pengetahuan:

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

Ekspor & Impor Agen

Bagikan agen sebagai paket portabel — di seluruh perangkat, tim, atau Hub Komunitas.

Ekspor agen:

POST /v1/agents/{id}/export

Mengembalikan paket JSON yang berisi definisi agen, persyaratan alat (berasal dari alat yang diaktifkan), persyaratan konektor (penyedia OAuth mana yang diperlukan), dan templat pemicu. Metadata sinkronisasi dihapus — paket tersebut adalah cetak biru yang bersih dan mandiri.

Impor agen:

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

{
  \"package\": {
    \"$schema\": \"caiioo.agent.package/v1\",
    \"agent\": {
      \"id\": \"shared-research-agent\",
      \"branding\": { \"name\": \"Agen Riset\", \"description\": \"Dari tim\" },
      \"defaultSettings\": { \"systemPrompt\": \"Anda meneliti berbagai hal.\" },
      \"settingLevels\": {}
    },
    \"toolRequirements\": [
      { \"toolId\": \"web_browsing\", \"enabled\": true },
      { \"toolId\": \"search_tools\", \"enabled\": true }
    ]
  }
}

Mengembalikan 201 dengan agen yang diinstal. Tabrakan ID dengan agen bawaan atau agen yang sudah ada mengembalikan 409.

Penanganan Kesalahan

API menggunakan kode status HTTP standar:

Kode Arti
200 Berhasil
201 Dibuat
202 Diterima (operasi asinkron dimulai)
204 Dihapus (tidak ada konten)
400 Permintaan buruk — periksa bidang error untuk detailnya
401 Tidak sah — rahasia sesi hilang atau tidak valid
403 Terlarang — mis., mencoba memodifikasi agen bawaan
404 Tidak ditemukan
409 Konflik — mis., ID agen sudah ada
422 Kesalahan validasi — input tidak sesuai dengan skema alat
429 Batas kecepatan terlampaui — lihat anggaran batas kecepatan di bagian Autentikasi
500 Kesalahan server — periksa bidang error
501 Belum diimplementasikan — fitur ada tetapi tidak tersedia dengan cara ini
503 Layanan tidak tersedia — penyimpanan atau penyedia belum siap

Semua respons kesalahan menyertakan { \"error\": \"pesan yang dapat dibaca manusia\" }.

Contoh Mulai Cepat

Berikut adalah alur kerja lengkap: buat agen, jalankan, dan alirkan hasilnya.

# 1. Buat agen kustom
curl -X POST http://localhost:3847/v1/agents \
  -H "Authorization: Bearer $API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "id": "quick-summarizer",
    "branding": { "name": "Peringkas Cepat" },
    "defaultSettings": {
      "systemPrompt": "Rangkum input apa pun secara ringkas dalam 3 poin bulet.",
      "enabledTools": { "web_browsing": true }
    },
    "settingLevels": {}
  }'

# 2. Jalankan secara asinkron
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": "Rangkum https://en.wikipedia.org/wiki/Artificial_intelligence" }, "mode": "async" }')

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

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

# 4. Ekspor agen untuk dibagikan
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.