Referensi API Agen Jenova
URL Dasar: https://api.jenova.ai/v1
Autentikasi: Bearer token di header Authorization
Daftar Isi
- Gambaran Umum
- Mulai Cepat
- Konsep Inti
- Autentikasi
- Titik Akhir API
- Streaming (SSE)
- Integrasi Server MCP
- Penagihan
- Batas Kecepatan
- Penanganan Galat
- Paginasi
- Pelokalan
- Privasi dan Data
- Dukungan
Gambaran Umum
Jalankan agen khusus di produk atau alur kerja Anda dalam hitungan menit. Siapkan agen Anda untuk tugas apa pun, pilih model dan tool apa pun, dan biarkan Jenova menangani agent harness, basis data, dan skalabilitas.
Stack Agen Lengkap:
- Agent Harness Terkelola: Satu panggilan masuk, pekerjaan selesai keluar. Agen Anda melakukan riset, menalar, memanggil tool, dan menghasilkan file — persis sesuai instruksi Anda.
- Konteks dan Memori Tanpa Batas: Pengelolaan konteks berbasis RAG dan pelacakan status sesi milik Jenova sendiri memungkinkan memori tanpa batas di dalam percakapan.
- Pustaka Tool dan MCP: Terhubung ke pustaka 30+ tool dan server MCP kami, seperti pencarian, pembuatan gambar, email, dan lainnya — atau sambungkan server MCP Anda sendiri.
- Beralih ke Model Apa Pun dengan Mulus: Deploy model dari OpenAI, Anthropic, Google, xAI, atau penyedia open source terkemuka, dan beralih di antara model tersebut dengan satu parameter.
- Pengetahuan dan RAG Terkelola: Jenova menangani pipeline RAG end-to-end — chunking, pengindeksan, penyimpanan, dan retrieval.
- Terbukti di Skala Besar: Deploy pada infrastruktur teruji yang menjalankan ratusan agen live di produksi. Tidak ada kluster yang perlu disiapkan, diskalakan, atau dirawat.
Mulai Cepat
1. Dapatkan Kunci API Anda
Buat kunci API dari dasbor pengembang di www.jenova.ai/platform. Kunci menggunakan format jnv_sk_* dan diteruskan sebagai Bearer token.
2. Pilih atau Buat Agen
Pilih agen siap pakai dari platform, atau buat agen kustom di dasbor dengan instruksi, pengaturan model, berkas basis pengetahuan, alat, dan server MCP.
3. Kirim Pesan Pertama Anda
Buat sesi dan kirim pesan dalam satu panggilan:
curl -N -X POST https://api.jenova.ai/v1/messages \
-H "Authorization: Bearer jnv_sk_your_api_key" \
-H "Content-Type: application/json" \
-d '{
"agent": "my-support-agent",
"user": "user_12345",
"content": "What can you help me with?"
}'
Respons dialirkan kembali sebagai Server-Sent Events:
event: stream_started
data: {"session_id":"ses_xyz789","run_id":"run_abc123","agent":"my-support-agent"}
event: stream_delta
data: {"session_id":"ses_xyz789","run_id":"run_abc123","chunk_content":"I can help you with ","seq":1}
event: stream_ended
data: {"session_id":"ses_xyz789","run_id":"run_abc123","success":true,"stop_reason":"end_run","usage":{"cost":"0.0032"}}
Tangkap session_id dari stream_started untuk permintaan lanjutan. Untuk respons JSON sinkron, lihat Kirim Pesan.
Konsep Inti
Agen
Agen AI yang Anda ajak berinteraksi melalui API. Setiap agen memiliki slug unik (misalnya, my-support-agent) yang digunakan sebagai nilai agent dalam panggilan API.
- Siap pakai: Pilih dari agen yang sudah ada di platform.
- Kustom: Konfigurasikan agen Anda sendiri di dasbor dengan instruksi, model, basis pengetahuan, alat, dan server MCP.
Sesi
Sebuah alur percakapan independen antara pengguna akhir dan agen.
- Identifier: ID dengan awalan (misalnya,
ses_abc123). - Ruang lingkup: Beberapa sesi dapat ada untuk agen dan pengguna akhir yang sama, masing-masing dengan status percakapan independen.
- Siklus hidup: Sesi bertahan tanpa batas waktu hingga dihapus melalui API. Untuk tugas sekali pakai yang tidak memerlukan sesi, gunakan
POST /messagesdenganephemeral: true. - Isolasi platform: Sesi API terpisah dari percakapan di aplikasi web Jenova. Pengguna akhir, riwayat sesi, dan penagihan bersifat independen antara API dan aplikasi web.
Pesan
Satu entri dalam riwayat percakapan sesi, dikembalikan oleh titik akhir Pesan. Setiap pesan berisi objek from terstruktur dengan type (user atau agent) dan name, ditambah type pesan:
external- pesan percakapan yang dimaksudkan untuk ditampilkan sebagai konten obrolan.internal- pesan opsional yang merepresentasikan langkah kerja agen selama eksekusi, seperti panggilan alat atau pengambilan data.
Eksekusi
Satu eksekusi agen yang dibuat saat Anda mengirim pesan. Sebuah eksekusi memiliki run_id, dapat mengalirkan peristiwa selama masih aktif, dan dapat menghasilkan satu atau beberapa pesan yang telah selesai. Setiap sesi hanya dapat memiliki satu eksekusi aktif pada satu waktu.
Pengguna Akhir
Bidang user membatasi ruang lingkup sesi ke seorang pengguna akhir di aplikasi Anda. Gunakan ID buram yang stabil, seperti ID pengguna internal Anda atau UUID. Hindari alamat email atau PII lain kecuali aplikasi Anda memang membutuhkannya. Sesi yang dibuat dengan nilai user yang sama akan dikelompokkan bersama, sehingga memungkinkan pencantuman sesi per pengguna.
Jika user tidak disertakan, sesi akan dibatasi ruang lingkupnya ke akun pengembang Anda dan tidak dapat difilter berdasarkan pengguna akhir nantinya. Sertakan user pada penggunaan produksi.
Untuk permintaan pada sesi yang sudah ada (titik akhir apa pun dengan {session_id} di jalurnya), user merupakan pengaman kepemilikan opsional. Jika Anda menyertakannya, nilainya harus cocok dengan nilai user yang digunakan saat sesi dibuat; jika tidak, API akan mengembalikan 404 session_not_owned. Kirimkan sebagai parameter kueri pada permintaan GET dan DELETE, dan dalam isi JSON pada permintaan POST dan PATCH. Parameter kueri user pada permintaan POST atau PATCH mengembalikan 400 bad_request.
Autentikasi
Autentikasi setiap permintaan dengan token Bearer di header Authorization:
Authorization: Bearer jnv_sk_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Kunci API dibuat dari dasbor pengembang.
User-Agent bersifat opsional. SDK dapat mengaturnya untuk keperluan diagnostik, tetapi API tidak mewajibkannya.
Format kunci: Kunci dimulai dengan prefiks jnv_sk_ diikuti oleh string acak yang dienkode base62.
Batas: Setiap akun pengembang dapat memiliki hingga 10 kunci API aktif.
Titik Akhir API
API Pesan
Pengiriman pesan adalah jalur API utama. Gunakan POST /messages untuk pesan pertama; permintaan ini membuat sesi dan memulai eksekusi dalam satu permintaan. Gunakan POST /sessions/{session_id}/messages saat melanjutkan session_id yang sudah disimpan.
Kirim Pesan
POST /messages
Membuat sesi persisten dan mengirim pesan pertama dalam satu permintaan. Setel ephemeral: true untuk permintaan sekali pakai berbasis streaming yang tidak mengembalikan ID sesi dan tidak dapat dilanjutkan. Datanya dihapus segera setelah permintaan selesai.
Isi Permintaan
| Bidang | Tipe | Wajib | Default | Deskripsi |
|---|---|---|---|---|
agent | string | Ya | - | Identifier slug agen |
content | string | Kondisional | - | Teks pesan. Wajib kecuali file_urls disediakan |
file_urls | string[] | Kondisional | - | URL berkas yang akan dilampirkan. Wajib kecuali content disediakan |
user | string | Tidak | - | Identifier pengguna akhir eksternal Anda (maksimal 255 karakter). Jika tidak disertakan, defaultnya adalah akun pengembang Anda |
session_name | string | Tidak | - | Nama tampilan untuk sesi baru (maksimal 200 karakter) |
ephemeral | boolean | Tidak | false | Permintaan sekali pakai berbasis streaming saja. Tidak mengembalikan ID sesi, tidak dapat dilanjutkan, dan datanya dihapus segera setelah permintaan selesai |
stream | boolean | Tidak | true | true untuk streaming SSE, false untuk JSON. Otorisasi MCP mengharuskan streaming |
include_progress | boolean | Tidak | true | Setel ke false untuk menghilangkan peristiwa stream_progress. Hanya untuk streaming |
model | string | Tidak | - | Penggantian model satu kali khusus untuk permintaan ini saja. Gunakan ID model yang stabil seperti claude-sonnet-5. Tidak mengubah model default sesi |
additional_context | object[] | Tidak | - | Konteks bernama khusus untuk permintaan ini. Lihat Konteks Tambahan |
Contoh - Streaming (default)
curl -N -X POST https://api.jenova.ai/v1/messages \
-H "Authorization: Bearer jnv_sk_xxx" \
-H "Content-Type: application/json" \
-d '{
"agent": "my-support-agent",
"user": "user_12345",
"content": "Hello, I need help with my account"
}'
Respons berupa stream SSE (lihat Streaming (SSE) untuk format peristiwa). Permintaan persisten menyertakan session_id yang baru; permintaan dengan ephemeral: true tidak menyertakan session_id dan harus menggunakan streaming.
Contoh - JSON (tanpa streaming)
curl -X POST https://api.jenova.ai/v1/messages \
-H "Authorization: Bearer jnv_sk_xxx" \
-H "Content-Type: application/json" \
-d '{
"agent": "my-support-agent",
"user": "user_12345",
"content": "Hello, I need help with my account",
"stream": false
}'
Respons
Respons streaming memancarkan peristiwa SSE yang didokumentasikan pada Streaming (SSE). Respons tanpa streaming mengembalikan objek pesan beserta stop_reason dan usage untuk permintaan tersebut, seperti yang ditunjukkan pada Lanjutkan Sesi. stop_reason bernilai end_run, atau user_cancelled jika eksekusi dibatalkan setelah agen menghasilkan pesan.
Jika eksekusi dibatalkan sebelum agen menghasilkan pesan, API mengembalikan 200 OK dengan status: "cancelled", session_id, run_id, stop_reason: "user_cancelled", dan usage.
Jika eksekusi tanpa streaming masih diproses setelah 90 detik, API mengembalikan 202 Accepted dengan status: "processing", session_id, run_id, dan message yang mudah dibaca manusia. Eksekusi tetap berlanjut setelah respons diberikan atau klien terputus; periksa pesan-pesan pada sesi tersebut, atau gunakan streaming untuk alur kerja yang lebih panjang.
Galat
| Status | Kode | Kondisi |
|---|---|---|
| 400 | missing_required_field | agent wajib diisi |
| 400 | invalid_payload | JSON tidak valid atau suatu bidang memiliki tipe yang tidak valid |
| 400 | bad_request | Mode ephemeral tidak valid, additional_context tidak valid, atau user/session_name melebihi panjang maksimumnya |
| 400 | content_or_uploaded_files_required | content maupun file_urls tidak disediakan |
| 400 | content_too_long | Isi pesan melebihi 32.000 token |
| 400 | exceed_max_upload_files | Lebih dari 10 URL berkas yang berbeda dalam satu permintaan |
| 400 | unsupported_file_format | Suatu URL berkas memiliki ekstensi berkas yang tidak didukung |
| 400 | invalid_file_url | Suatu URL berkas tidak valid atau bukan HTTPS |
| 400 | invalid_model_selection | model bukan ID model yang valid, atau model default agen tidak tersedia |
| 402 | insufficient_credits | Kredit tidak cukup untuk membuat sesi atau mengirim pesan |
| 404 | agent_not_found | Agen tidak ada atau tidak dapat diakses oleh akun Anda |
Lanjutkan Sesi
POST /sessions/{session_id}/messages
Mengirim Pesan ke Sesi persisten yang sudah ada dan menerima respons agen. Respons melakukan streaming melalui SSE secara default; atur stream: false untuk JSON.
Isi Permintaan
| Bidang | Tipe | Wajib | Default | Deskripsi |
|---|---|---|---|---|
content | string | Kondisional | - | Teks Pesan. Wajib kecuali file_urls disediakan |
file_urls | string[] | Kondisional | - | URL berkas yang akan dilampirkan. Wajib kecuali content disediakan |
stream | boolean | Tidak | true | true untuk streaming SSE, false untuk JSON. Otorisasi MCP memerlukan streaming |
include_progress | boolean | Tidak | true | Setel ke false untuk menghilangkan peristiwa stream_progress. Hanya untuk streaming |
model | string | Tidak | - | Penggantian Model satu kali khusus untuk permintaan ini saja. Gunakan ID Model yang stabil seperti claude-sonnet-5. Tidak mengubah Model default Sesi |
additional_context | object[] | Tidak | - | Konteks bernama khusus untuk permintaan ini. Lihat Konteks Tambahan |
Contoh - Streaming (default)
curl -N -X POST https://api.jenova.ai/v1/sessions/ses_abc123/messages \
-H "Authorization: Bearer jnv_sk_xxx" \
-H "Content-Type: application/json" \
-d '{
"content": "How do I reset my password?"
}'
Contoh - JSON (non-streaming)
curl -X POST https://api.jenova.ai/v1/sessions/ses_abc123/messages \
-H "Authorization: Bearer jnv_sk_xxx" \
-H "Content-Type: application/json" \
-d '{
"content": "How do I reset my password?",
"stream": false
}'
Respons 200 OK
{
"id": "msg_xyz789",
"session_id": "ses_abc123",
"sequence": 4,
"from": {
"type": "agent",
"name": "my-support-agent"
},
"type": "external",
"time": "2026-05-19T10:31:05Z",
"content": "To reset your password, go to Settings > Security > Change Password...",
"model": "claude-sonnet-5",
"files": [],
"stop_reason": "end_run",
"usage": {
"cost": "0.0015"
}
}
Jika Sesi sudah memiliki Eksekusi aktif atau Pesan yang tertunda, API mengembalikan JSON 202 Accepted dengan status: "queued", session_id, run_id, dan message_id. Pesan pengguna akan diproses oleh Eksekusi yang aktif. Permintaan dengan additional_context akan mengembalikan 409 busy sebagai gantinya.
Respons tanpa streaming mengikuti aturan yang sama dengan Kirim Pesan, termasuk respons status: "cancelled" ketika Eksekusi dibatalkan sebelum Agen menghasilkan Pesan.
Galat
| Status | Kode | Kondisi |
|---|---|---|
| 400 | invalid_payload | JSON tidak valid atau suatu bidang memiliki tipe yang tidak valid |
| 400 | bad_request | additional_context tidak valid |
| 400 | content_or_uploaded_files_required | content maupun file_urls tidak disediakan |
| 400 | content_too_long | Isi Pesan melebihi 32.000 token |
| 400 | exceed_max_upload_files | Lebih dari 10 URL berkas yang berbeda dalam satu Permintaan |
| 400 | unsupported_file_format | Suatu URL berkas memiliki ekstensi berkas yang tidak didukung |
| 400 | invalid_file_url | Suatu URL berkas tidak valid atau bukan HTTPS |
| 400 | invalid_model_selection | model bukan ID Model yang valid, atau Model Sesi sudah tidak tersedia |
| 402 | insufficient_credits | Kredit tidak cukup untuk mengirim Pesan |
| 404 | session_not_found | Sesi tidak ditemukan |
| 404 | session_not_owned | Sesi milik developer lain atau tidak sesuai dengan user yang diberikan |
| 409 | busy | Sesi untuk sementara tidak tersedia karena pembaruan lain sedang berlangsung, atau additional_context dikirim saat Sesi memiliki Eksekusi aktif atau Pesan yang tertunda |
| 429 | too_many_pending | Sesi sudah memiliki 200 Pesan yang mengantre |
| 503 | service_unavailable | Layanan untuk sementara tidak tersedia |
Idempotensi
POST /messages, POST /sessions/{session_id}/messages, dan POST /invoke menerima header Idempotency-Key opsional (maksimal 255 karakter). Gunakan kunci unik untuk setiap pengiriman pengguna logis agar percobaan ulang jaringan atau pengiriman ganda tidak membuat eksekusi duplikat. Kunci disimpan selama 24 jam.
curl -N -X POST https://api.jenova.ai/v1/messages \
-H "Authorization: Bearer jnv_sk_xxx" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: send-user_12345-2026-05-19T10:30:00Z" \
-d '{
"agent": "my-support-agent",
"user": "user_12345",
"content": "Hello"
}'
Non-streaming: Mencoba ulang akan mengembalikan respons yang tersimpan dengan header Idempotent-Replayed: true, termasuk galat yang dikembalikan setelah permintaan mulai diproses. Respons 202 Accepted yang tersimpan diputar ulang tanpa perubahan; gunakan Dapatkan Status Eksekusi atau Daftar Pesan untuk memeriksa hasilnya. Permintaan yang ditolak sebelum pemrosesan dimulai, seperti galat validasi atau kredit, tidak disimpan, sehingga percobaan ulang akan dievaluasi kembali.
Streaming: Stream tidak diputar ulang. Untuk POST /messages dan POST /sessions/{session_id}/messages, mencoba ulang saat sedang berjalan atau setelah selesai akan mengembalikan galat idempotensi dengan run_id asli dan, untuk permintaan yang persisten, session_id. Untuk permintaan yang persisten, gunakan Dapatkan Status Eksekusi untuk memeriksa eksekusi yang aktif, atau Daftar Pesan untuk mengambil hasil yang telah tersimpan. Hasil POST /invoke yang di-stream tidak dapat diambil setelah stream ditutup. Percobaan ulang POST /invoke mengembalikan id asli, bukan run_id dan session_id.
Contoh percobaan ulang streaming yang telah selesai:
HTTP/1.1 409 Conflict
Content-Type: application/json
{
"error": {
"code": "idempotency_key_reused",
"message": "This Idempotency-Key has already completed. Streaming responses cannot be replayed; use the returned session_id and run_id to retrieve the result."
},
"idempotency": {
"status": "completed",
"session_id": "ses_abc123",
"run_id": "run_abc123"
}
}
Galat idempotensi
| Status | Kode | Kondisi |
|---|---|---|
| 400 | bad_request | Idempotency-Key melebihi panjang maksimumnya |
| 409 | idempotency_key_reused | Kunci yang sama digunakan dengan permintaan yang berbeda |
| 409 | idempotency_key_in_use | Permintaan asli masih berjalan |
| 409 | idempotency_key_reused | Permintaan streaming asli sudah selesai dan tidak dapat diputar ulang |
Daftar Pesan
GET /sessions/{session_id}/messages
Mengembalikan daftar Pesan Sesi dengan Paginasi. Secara default, hanya Pesan percakapan external yang dikembalikan. Halaman pertama berisi Pesan terbaru; dalam setiap halaman, Pesan diurutkan secara kronologis (yang paling lama lebih dulu). sequence adalah nomor urutan Pesan dalam Sesi.
Parameter Kueri
| Parameter | Tipe | Default | Maks | Deskripsi |
|---|---|---|---|---|
limit | integer | 20 | 100 | Jumlah Pesan per halaman |
cursor | string | - | - | Kursor Paginasi |
include | string | external | - | Tipe Pesan yang dikembalikan: external, internal, atau all |
Contoh
curl "https://api.jenova.ai/v1/sessions/ses_abc123/messages?limit=50" \
-H "Authorization: Bearer jnv_sk_xxx"
Respons 200 OK
{
"items": [
{
"id": "msg_002",
"session_id": "ses_abc123",
"sequence": 4,
"from": {
"type": "agent",
"name": "my-support-agent"
},
"type": "external",
"time": "2026-05-19T10:31:05Z",
"content": "To reset your password, go to Settings > Security...",
"model": "claude-sonnet-5",
"stop_reason": "end_run"
}
],
"next_cursor": "",
"has_more": false
}
Objek Pesan
| Bidang | Tipe | Deskripsi |
|---|---|---|
id | string | ID Pesan (berawalan msg_) |
session_id | string | ID Sesi induk |
sequence | integer | Nomor urutan dalam Sesi. Nomor dapat digunakan kembali setelah Pesan dihapus |
from | object | Objek pengirim dengan type (user atau agent) dan name |
type | string | external untuk Pesan percakapan, atau internal untuk langkah kerja Agen |
time | string | Stempel waktu ISO 8601 |
content | string | Konten teks. Ada pada Pesan eksternal |
model | string | ID Model stabil yang menghasilkan respons. Hanya ada pada Pesan Agen |
files | array | File yang dilampirkan atau dihasilkan yang disertakan dengan Pesan. Lihat Objek File di bawah. Tidak disertakan pada Daftar Pesan dan Dapatkan Pesan jika Pesan tidak memiliki file |
stop_reason | string | Ada pada Pesan Agen eksternal yang memiliki konten. Nilainya adalah end_run |
agent | string | Slug Agen yang mengeksekusi, bila tersedia |
agent_name | string | Nama tampilan Agen yang mengeksekusi, bila tersedia |
progress_events | array | Aktivitas yang tercatat untuk Pesan internal, bila tersedia. Setiap entri memiliki bidang yang sama dengan peristiwa stream_progress |
Objek File
| Bidang | Tipe | Deskripsi |
|---|---|---|
file_id | string | ID file Jenova. Kosong bila tidak diketahui |
name | string | Nama file |
url | string | URL file. Kosong bila tidak diketahui |
format | string | Format file huruf kecil, seperti pdf, png, atau csv |
size | integer | Ukuran file dalam byte. 0 bila tidak diketahui |
Galat
| Status | Kode | Kondisi |
|---|---|---|
| 400 | bad_request | Parameter kueri tidak valid |
| 404 | session_not_found | Sesi tidak ada |
| 404 | session_not_owned | Sesi milik developer lain atau tidak sesuai dengan user yang diberikan |
Dapatkan Pesan
GET /sessions/{session_id}/messages/{message_id}
Mengambil satu Pesan berdasarkan ID.
Parameter Kueri
| Parameter | Tipe | Default | Deskripsi |
|---|---|---|---|
include | string | external | Tipe Pesan yang dapat dikembalikan: external, internal, atau all |
Respons 200 OK
Mengembalikan satu objek Pesan dengan struktur yang sama seperti respons daftar.
Galat
| Status | Kode | Kondisi |
|---|---|---|
| 400 | bad_request | Parameter kueri tidak valid |
| 404 | session_not_found | Sesi tidak ada |
| 404 | session_not_owned | Sesi milik developer lain atau tidak sesuai dengan user yang diberikan |
| 404 | not_found | Pesan tidak ada dalam Sesi ini |
Lampiran File
Berikan URL HTTPS yang dapat diakses publik pada bidang file_urls.
| Batas | Nilai |
|---|---|
| Maksimum file per Pesan | 10 |
| Ukuran file maksimum | 20 MB per file |
Format yang didukung
- Gambar: JPG, JPEG, PNG, WebP
- Dokumen: PDF, DOCX, XLSX, PPTX, TXT, CSV, RTF, MD, HTML, XML, JSON, LOG
- Kode: JS, TS, TSX, JSX, PY, Java, Go, C, CPP, H, HPP, CS, RB, PHP, RS, Swift, KT, Scala, SQL, CSS, YAML, YML
URL file diambil saat agen membacanya selama eksekusi, bukan saat permintaan diterima. URL yang tidak dapat diambil, atau file yang lebih besar dari 20 MB, tidak akan dibaca; permintaan itu sendiri tidak ditolak.
Saat mendaftar Pesan, file yang dilampirkan muncul dalam array files pada Pesan tersebut.
Konteks Tambahan
Kirimkan konteks bernama untuk satu Pesan melalui additional_context, seperti detail akun pengguna akhir. Konteks ini tidak disimpan dalam riwayat pesan.
| Bidang | Tipe | Wajib | Deskripsi |
|---|---|---|---|
name | string | Ya | Huruf kecil, angka, dan garis bawah, diawali huruf (maks. 64 karakter). Unik dalam satu permintaan, dengan mengabaikan garis bawah dan bentuk jamak |
content | string | Ya | Teks konteks. Tidak boleh kosong (maks. 12.000 token) |
| Batas | Nilai |
|---|---|
| Maksimum item per Pesan | 4 |
| Maksimum token per item | 12.000 |
Gunakan nama yang deskriptif seperti customer_profile atau order_details.
Item dengan name atau content yang tidak ada atau bukan string mengembalikan 400 invalid_payload. Item tidak valid lainnya mengembalikan 400 bad_request.
curl -N -X POST https://api.jenova.ai/v1/sessions/ses_abc123/messages \
-H "Authorization: Bearer jnv_sk_xxx" \
-H "Content-Type: application/json" \
-d '{
"content": "How do I reset my password?",
"additional_context": [
{
"name": "customer_profile",
"content": "Plan: Pro. Last login: 2026-05-18."
}
]
}'
API Sesi
Sesi adalah percakapan persisten antara Pengguna Akhir dan Agen. Sebagian besar integrasi dapat membuatnya secara implisit dengan POST /messages.
Buat Sesi
POST /sessions
Membuat sesi persisten kosong yang terikat pada agen tertentu. Gunakan ini saat Anda memerlukan ID sesi sebelum pesan pertama; jika tidak, sebaiknya gunakan POST /messages.
Catatan:
ephemeraltidak diterima padaPOST /sessions; gunakanPOST /messagesdenganephemeral: trueuntuk permintaan sekali pakai.
Isi Permintaan
| Bidang | Tipe | Wajib | Deskripsi |
|---|---|---|---|
agent | string | Ya | Pengenal slug agen |
user | string | Tidak | Pengenal pengguna akhir eksternal Anda (maks. 255 karakter). Jika dihilangkan, defaultnya adalah akun developer Anda |
session_name | string | Tidak | Nama tampilan untuk sesi (maks. 200 karakter) |
Contoh
curl -X POST https://api.jenova.ai/v1/sessions \
-H "Authorization: Bearer jnv_sk_xxx" \
-H "Content-Type: application/json" \
-d '{
"agent": "my-support-agent",
"user": "user_12345",
"session_name": "Billing inquiry"
}'
Respons 201 Created
{
"id": "ses_abc123",
"session_name": "Billing inquiry",
"agent": "my-support-agent",
"user": "user_12345",
"model": "claude-sonnet-5",
"created_at": "2026-05-19T10:30:00Z",
"updated_at": "2026-05-19T10:30:00Z"
}
Objek Sesi
| Bidang | Tipe | Deskripsi |
|---|---|---|
id | string | ID sesi (berawalan ses_) |
session_name | string | Nama tampilan |
agent | string | Slug agen |
agent_details | object | Detail agen dengan display_name. Hanya ada jika diminta dengan include=agent |
user | string | Pengenal pengguna akhir. null jika sesi dibuat tanpa user |
model | string | Model yang digunakan jika pesan tidak menentukan model. Disetel ke model default agen saat sesi dibuat. Kosong jika agen membiarkan Jenova memilih model |
created_at | string | Stempel waktu ISO 8601 |
updated_at | string | Stempel waktu ISO 8601 |
Galat
| Status | Kode | Kondisi |
|---|---|---|
| 400 | invalid_payload | JSON tidak valid atau suatu bidang memiliki tipe yang tidak valid |
| 400 | missing_required_field | agent diwajibkan |
| 400 | bad_request | ephemeral disertakan, atau user/session_name melebihi panjang maksimumnya |
| 402 | insufficient_credits | Kredit tidak cukup untuk membuat sesi |
| 404 | agent_not_found | Agen tidak ada atau tidak dapat diakses oleh akun Anda |
Daftar Sesi
GET /sessions
Mengembalikan daftar sesi Anda yang dipaginasi, diurutkan berdasarkan yang paling baru diperbarui.
Parameter Kueri
| Parameter | Tipe | Default | Maks | Deskripsi |
|---|---|---|---|---|
limit | integer | 20 | 100 | Jumlah item per halaman |
cursor | string | - | - | Kursor paginasi |
user | string | - | - | Filter berdasarkan pengenal pengguna akhir (maks. 255 karakter) |
agent | string | - | - | Filter berdasarkan slug agen |
include | string | - | - | Setel ke agent untuk menambahkan agent_details ke setiap sesi |
Contoh
curl "https://api.jenova.ai/v1/sessions?user=user_12345&limit=10" \
-H "Authorization: Bearer jnv_sk_xxx"
Respons 200 OK
{
"items": [
{
"id": "ses_abc123",
"session_name": "Billing inquiry",
"agent": "my-support-agent",
"user": "user_12345",
"model": "claude-sonnet-5",
"created_at": "2026-05-19T10:30:00Z",
"updated_at": "2026-05-19T11:15:00Z"
}
],
"next_cursor": "2026-05-19T11:15:00Z|ses_abc123",
"has_more": true
}
Galat
| Status | Kode | Kondisi |
|---|---|---|
| 400 | bad_request | Parameter kueri tidak valid |
Dapatkan Sesi
GET /sessions/{session_id}
Mengambil satu sesi berdasarkan ID.
Parameter Kueri
| Parameter | Tipe | Deskripsi |
|---|---|---|
include | string | Setel ke agent untuk menambahkan agent_details ke sesi |
Respons 200 OK
Mengembalikan objek sesi.
Galat
| Status | Kode | Kondisi |
|---|---|---|
| 400 | bad_request | Parameter kueri tidak valid |
| 404 | session_not_found | Sesi tidak ada |
| 404 | session_not_owned | Sesi dimiliki oleh developer lain atau tidak cocok dengan user yang diberikan |
Ubah Nama Sesi
PATCH /sessions/{session_id}
Memperbarui nama tampilan sebuah sesi.
Isi Permintaan
| Bidang | Tipe | Wajib | Deskripsi |
|---|---|---|---|
session_name | string | Ya | Nama tampilan baru (maksimal 200 karakter) |
Respons 200 OK
Mengembalikan objek sesi yang telah diperbarui.
Galat
| Status | Kode | Kondisi |
|---|---|---|
| 400 | invalid_payload | JSON tidak valid atau suatu bidang memiliki tipe yang tidak valid |
| 400 | missing_required_field | session_name wajib diisi |
| 400 | bad_request | session_name melebihi panjang maksimalnya |
| 404 | session_not_found | Sesi tidak ada |
| 404 | session_not_owned | Sesi dimiliki oleh developer lain atau tidak cocok dengan user yang diberikan |
| 409 | busy | Sesi untuk sementara tidak tersedia karena pembaruan lain sedang berlangsung |
Hapus Sesi
DELETE /sessions/{session_id}
Menghapus sesi secara permanen beserta semua pesannya. Sesi tersebut tidak boleh memiliki eksekusi yang sedang aktif.
Respons 204 No Content
Galat
| Status | Kode | Kondisi |
|---|---|---|
| 404 | session_not_found | Sesi tidak ada |
| 404 | session_not_owned | Sesi dimiliki oleh developer lain atau tidak cocok dengan user yang diberikan |
| 409 | busy | Sesi memiliki eksekusi yang sedang aktif - batalkan terlebih dahulu |
Operasi
Titik akhir ini merupakan kontrol pemulihan dan pengeditan untuk sesi yang persisten. Sebagian besar integrasi hanya membutuhkan Batalkan Eksekusi Aktif; gunakan operasi lain saat Anda memang bermaksud mengubah atau memulihkan status sesi. Semua operasi mendukung penjaga kepemilikan opsional user yang dijelaskan pada Pengguna Akhir.
Batalkan Eksekusi Aktif
POST /sessions/{session_id}/cancel
Membatalkan eksekusi agen yang aktif. Ini tidak menghapus pesan yang sudah selesai sebelum pembatalan.
Isi Permintaan
| Bidang | Tipe | Wajib | Deskripsi |
|---|---|---|---|
run_id | string | Tidak | Penjaga eksekusi kedaluwarsa opsional. Jika diberikan dan tidak cocok dengan eksekusi yang aktif, API mengembalikan 409 stale_run |
Respons 204 No Content
Galat
| Status | Kode | Kondisi |
|---|---|---|
| 400 | invalid_payload | JSON tidak valid atau suatu bidang memiliki tipe yang tidak valid |
| 400 | cancel_not_allowed | Tidak ada eksekusi aktif untuk dibatalkan, atau pembatalan tidak diizinkan |
| 404 | session_not_found | Sesi tidak ada |
| 404 | session_not_owned | Sesi dimiliki oleh developer lain atau tidak cocok dengan user yang diberikan |
| 409 | stale_run | run_id yang diberikan tidak cocok dengan eksekusi yang aktif |
Urungkan Eksekusi Aktif
POST /sessions/{session_id}/undo
Membatalkan eksekusi yang aktif, menunggu hingga berhenti, kemudian menghapus pesan apa pun yang sudah ditambahkannya. Tidak ada keluaran tambahan yang disimpan setelah pengurungan dijalankan.
Isi Permintaan
| Bidang | Tipe | Wajib | Deskripsi |
|---|---|---|---|
run_id | string | Tidak | Penjaga eksekusi kedaluwarsa opsional. Jika diberikan dan tidak cocok dengan eksekusi yang aktif, API mengembalikan 409 stale_run |
Respons 200 OK
{
"session_id": "ses_abc123",
"run_id": "run_abc123",
"deleted": ["msg_002", "msg_001"]
}
Jika eksekusi dibatalkan sebelum ada pesan yang selesai, deleted berupa array kosong.
Galat
| Status | Kode | Kondisi |
|---|---|---|
| 400 | invalid_payload | JSON tidak valid atau suatu bidang memiliki tipe yang tidak valid |
| 400 | cancel_not_allowed | Tidak ada eksekusi aktif untuk diurungkan, atau pembatalan tidak diizinkan |
| 404 | session_not_found | Sesi tidak ada |
| 404 | session_not_owned | Sesi dimiliki oleh developer lain atau tidak cocok dengan user yang diberikan |
| 409 | stale_run | run_id yang diberikan tidak cocok dengan eksekusi yang aktif |
| 409 | busy | Sesi untuk sementara tidak tersedia karena pembaruan lain sedang berlangsung |
Hapus Pesan Terbaru
POST /sessions/{session_id}/messages/delete
Menghapus count pesan terbaru dari sesi yang sedang idle, termasuk pesan internal. Gunakan include=all pada Daftar Pesan untuk melihatnya. Sesi tidak boleh memiliki eksekusi yang aktif.
Isi Permintaan
| Bidang | Tipe | Wajib | Deskripsi |
|---|---|---|---|
count | integer | Ya | Jumlah pesan terbaru yang akan dihapus dari akhir (harus lebih besar dari 0). Nilai di atas 100 diperlakukan sebagai 100 |
Respons 200 OK
{
"deleted": ["msg_002", "msg_001"]
}
Galat
| Status | Kode | Kondisi |
|---|---|---|
| 400 | invalid_payload | JSON tidak valid atau suatu bidang memiliki tipe yang tidak valid |
| 400 | bad_request | count tidak ada, nol, atau negatif; atau tidak ada pesan untuk dihapus |
| 404 | session_not_found | Sesi tidak ada |
| 404 | session_not_owned | Sesi milik developer lain atau tidak cocok dengan user yang diberikan |
| 409 | busy | Sesi memiliki eksekusi yang aktif |
Fork Sesi
POST /sessions/{session_id}/fork
Membuat sesi baru dengan menyalin sesi sumber hingga pesan tertentu. Sesi sumber tidak boleh memiliki eksekusi yang aktif.
Isi Permintaan (opsional)
| Bidang | Tipe | Wajib | Deskripsi |
|---|---|---|---|
message_id | string | Tidak | ID pesan titik fork. Jika tidak disertakan, fork dilakukan dari pesan terakhir |
Respons 201 Created
Mengembalikan objek sesi yang baru dibuat dengan struktur yang sama seperti pembuatan sesi.
Galat
| Status | Kode | Kondisi |
|---|---|---|
| 400 | invalid_payload | JSON tidak valid atau suatu bidang memiliki tipe yang tidak valid |
| 400 | bad_request | message_id tidak valid |
| 402 | insufficient_credits | Kredit tidak cukup untuk melakukan fork sesi |
| 404 | not_found | message_id tidak ada dalam sesi ini |
| 404 | session_not_found | Sesi tidak ada |
| 404 | session_not_owned | Sesi milik developer lain atau tidak cocok dengan user yang diberikan |
| 409 | busy | Sesi sumber memiliki eksekusi yang aktif |
Dapatkan Status Eksekusi
GET /sessions/{session_id}/runs/{run_id}
Mengembalikan status terkini dari eksekusi yang aktif. Gunakan ini setelah koneksi SSE terputus atau respons idempotensi yang mengembalikan run_id. Setelah eksekusi selesai, ambil hasilnya dengan GET /sessions/{session_id}/messages.
Respons 200 OK
{
"session_id": "ses_abc123",
"run_id": "run_abc123",
"status": "streaming",
"started_at": "2026-05-19T10:30:00Z",
"updated_at": "2026-05-19T10:30:06Z",
"content": "Partial visible response text so far"
}
status bernilai running selama agen sedang bekerja, streaming setelah teks respons mulai dihasilkan, atau ended sesaat setelah eksekusi selesai. Respons juga dapat mencakup progress_events berisi aktivitas terbaru, dalam format yang sama dengan stream_progress. Jika status bernilai ended atau permintaan mengembalikan 404 not_found, ambil pesan-pesan sesi.
Galat
| Status | Kode | Kondisi |
|---|---|---|
| 404 | session_not_found | Sesi tidak ada |
| 404 | session_not_owned | Sesi milik developer lain atau tidak cocok dengan user yang diberikan |
| 404 | not_found | Eksekusi tidak aktif untuk sesi ini |
Kredit
Dapatkan Saldo
GET /credits/balance
Mengembalikan saldo kredit Anda saat ini.
Respons 200 OK
{
"balance": "123.45"
}
API Agen
Buat dan edit agen khusus di dasbor. Dukungan API untuk membuat dan mengedit agen akan segera hadir.
Alur kerja terjadwal/latar belakang saat ini belum didukung melalui API. Dukungan akan segera hadir.
Daftar Agen
GET /agents
Mengembalikan agen yang tersedia untuk akun Anda. Gunakan nilai agent saat membuat sesi atau mengirim pesan.
Respons 200 OK
{
"agents": [
{
"agent": "jenova",
"display_name": "Jenova",
"description": "General-purpose Jenova agent"
},
{
"agent": "my-support-agent",
"display_name": "Support Agent",
"description": "Answers customer questions"
}
]
}
| Bidang | Tipe | Deskripsi |
|---|---|---|
agent | string | Slug agen yang stabil untuk diteruskan sebagai nilai agent |
display_name | string | Nama tampilan yang mudah dibaca manusia |
description | string | Deskripsi agen |
Model
Daftar Model
GET /models
Mengembalikan semua model yang tersedia untuk digunakan pada bidang model saat mengirim pesan atau memanggil POST /invoke.
Respons 200 OK
{
"models": [
{
"id": "claude-opus-4-8",
"name": "Claude Opus 4.8",
"thinking_variant": "claude-opus-4-8-thinking"
},
{
"id": "claude-opus-4-8-thinking",
"name": "Claude Opus 4.8 (Thinking)"
},
{
"id": "claude-sonnet-5",
"name": "Claude Sonnet 5",
"thinking_variant": "claude-sonnet-5-thinking"
}
]
}
| Bidang | Tipe | Deskripsi |
|---|---|---|
id | string | Identifikator model yang stabil. Teruskan ini sebagai nilai model pada Kirim Pesan atau Panggil Model |
name | string | Nama tampilan yang mudah dibaca manusia |
thinking_variant | string | ID model dari varian thinking/reasoning. Hanya ada pada model dasar yang mendukung reasoning |
Model dengan thinking_variant mendukung reasoning tingkat lanjut. Gunakan ID varian tersebut secara langsung pada bidang model untuk mengaktifkannya.
Jika tidak ada model yang ditentukan saat mengirim pesan, model milik sesi akan digunakan. Nilai ini disetel ke model default agen saat sesi dibuat.
Panggil Model
POST /invoke
Mengirim prompt langsung ke model, tanpa agen, Sesi, atau alat. Respons melakukan streaming melalui SSE secara default; atur stream: false untuk JSON.
Isi Permintaan
| Bidang | Tipe | Wajib | Default | Deskripsi |
|---|---|---|---|---|
model | string | Ya | - | ID model dari Daftar Model |
content | string | Ya | - | Prompt, termasuk instruksi apa pun |
stream | boolean | Tidak | true | true untuk streaming SSE, false untuk JSON |
user | string | Tidak | - | Identifier pengguna akhir eksternal Anda (maksimal 255 karakter). Jika tidak disertakan, defaultnya adalah akun pengembang Anda |
Contoh
curl -X POST https://api.jenova.ai/v1/invoke \
-H "Authorization: Bearer jnv_sk_xxx" \
-H "Content-Type: application/json" \
-d '{
"model": "claude-sonnet-5",
"content": "Describe a forest in one sentence.",
"stream": false
}'
Respons 200 OK
{
"id": "inv_abc123",
"model": "claude-sonnet-5",
"content": "Sunlight filters through tall pines onto a quiet, mossy floor.",
"usage": {
"cost": "0.0004"
}
}
Respons streaming mengirim stream_started, lalu event stream_delta saat model menghasilkan teks, dan diakhiri dengan stream_ended yang menyertakan usage. Gabungkan nilai chunk_content sesuai urutan seq untuk membangun respons yang di-stream. Jika permintaan gagal, stream_error dikirim sebelum stream_ended. Event menyertakan id sebagai pengganti session_id dan run_id.
usage.cost bernilai null jika biaya tidak tersedia. Jika permintaan non-streaming gagal setelah panggilan model dimulai, respons galat menyertakan bidang id dan usage tingkat atas.
Permintaan streaming dibatasi hingga 120 menit. Permintaan non-streaming menunggu hasil hingga 30 menit alih-alih mengembalikan 202 Accepted, dan mengembalikan galat jika hasil belum siap saat itu.
Galat
| Status | Kode | Kondisi |
|---|---|---|
| 400 | invalid_payload | JSON tidak valid atau suatu bidang memiliki tipe yang tidak valid |
| 400 | missing_required_field | content wajib diisi |
| 400 | content_too_long | Konten melebihi 32.000 token |
| 400 | bad_request | user melebihi panjang maksimumnya |
| 400 | invalid_model_selection | model tidak ada atau bukan ID model yang valid |
| 400 | content_policy_violation | Penyedia model menolak permintaan karena alasan kebijakan konten |
| 400 | llm_context_limit_reached | Input melebihi jendela konteks model |
| 402 | insufficient_credits | Kredit tidak cukup untuk memanggil model |
| 500 | internal_error | Galat server yang tidak terduga |
| 502 | llm_api_error | Galat pada penyedia model atau API model upstream |
| 502 | llm_empty_response | Model mengembalikan respons kosong |
| 502 | llm_reasoning_limit_reached | Model mencapai batas penalaran tanpa respons |
| 502 | llm_generation_limit_reached | Model mencapai batas generasi tanpa respons |
| 503 | service_unavailable | Layanan untuk sementara tidak tersedia |
Dokumentasi
GET /docs?lang=en
GET /doc?lang=en
Mengembalikan referensi ini dalam format Markdown. Gunakan lang untuk memilih bahasa.
Streaming (SSE)
Ketika stream dihilangkan atau bernilai true (default), respons pesan dikirimkan sebagai Server-Sent Events. Gunakan peristiwa message_completed untuk mengidentifikasi pesan yang siap untuk diambil atau dirender.
Waktu Tunggu: Koneksi SSE tetap terbuka hingga eksekusi berakhir. Eksekusi dibatasi hingga 120 menit. Permintaan pesan non-streaming menunggu hingga 90 detik, kemudian mengembalikan 202 Accepted sementara eksekusi terus berlangsung. Untuk POST /invoke non-streaming, lihat Panggil Model.
Header Koneksi
Stream pesan menetapkan header berikut:
Content-Type: text/event-stream
Cache-Control: no-cache
Connection: keep-alive
X-Accel-Buffering: no
X-Run-Id: run_abc123
X-Run-Id tersedia sebelum peristiwa SSE pertama. Stream POST /invoke tidak menetapkan X-Run-Id; gunakan id pada stream_started.
Sambungkan Ulang dan Pemulihan
Stream SSE tidak diulang (replay). Jika koneksi terputus pada permintaan persisten, gunakan session_id dan run_id yang telah ditangkap untuk memulihkan status:
curl "https://api.jenova.ai/v1/sessions/ses_abc123/runs/run_abc123" \
-H "Authorization: Bearer jnv_sk_xxx"
Jika eksekusi masih aktif, ini akan mengembalikan status terkini, teks sebagian, dan progres terbaru. Jika mengembalikan status: "ended" atau 404 not_found, eksekusi tersebut tidak lagi aktif; ambil pesan-pesan sesi untuk merekonsiliasi keluaran yang telah selesai:
curl "https://api.jenova.ai/v1/sessions/ses_abc123/messages?limit=20" \
-H "Authorization: Bearer jnv_sk_xxx"
Format Bingkai
Setiap bingkai SSE mengikuti format standar berikut:
event: <event_type>
data: <json_payload>
Dua baris baru mengakhiri setiap bingkai.
Jenis Peristiwa
Stream mencakup peristiwa siklus hidup, delta teks, pemikiran, progres, peringatan, penyelesaian pesan, koneksi MCP, error, final, dan ping. Beberapa jenis peristiwa hanya dikirim saat relevan.
Untuk permintaan efemeral (ephemeral: true), setiap peristiwa SSE menghilangkan session_id. Gunakan run_id saja untuk mengorelasikan peristiwa di dalam stream tersebut.
Untuk rekonsiliasi akhir pada permintaan persisten, tunggu stream_ended, lalu panggil Daftar Pesan.
Bidang umum pada peristiwa yang berlingkup eksekusi:
| Bidang | Deskripsi |
|---|---|
session_id | ID Sesi. Dihilangkan untuk stream efemeral. Catat nilai ini dari stream_started untuk permintaan lanjutan saat menggunakan POST /messages persisten |
run_id | ID Eksekusi saat ini, jika tersedia |
id | ID permintaan invoke (diawali dengan inv_). Hanya ada pada stream POST /invoke, yang tidak memiliki session_id maupun run_id |
stream_started
Dikirim sekali saat Eksekusi dimulai.
| Bidang | Deskripsi |
|---|---|
agent | Slug Agen Sesi, jika tersedia |
stream_delta
Dikirim berulang kali saat Agen menghasilkan teks respons yang terlihat. Gabungkan nilai chunk_content sesuai urutan seq untuk membangun respons yang di-stream.
event: stream_delta
data: {"session_id":"ses_abc123","run_id":"run_abc123","chunk_content":"To reset your ","seq":1}
| Bidang | Deskripsi |
|---|---|
chunk_content | Potongan teks |
seq | Urutan potongan yang monoton dalam stream |
stream_thinking
Dikirim berulang kali saat Agen mengeluarkan output thinking. Gunakan ini untuk indikator thinking terpisah atau tampilan trace; jangan menggabungkannya ke dalam teks respons akhir.
| Bidang | Deskripsi |
|---|---|
content | Potongan teks thinking |
stream_progress
Melaporkan aktivitas yang terlihat oleh pengguna selama pembuatan, seperti membaca dokumen, mencari di web, atau menunggu tindakan pengguna. Peristiwa ini dimaksudkan untuk tampilan UI sementara; abaikan bidang yang tidak dikenal. Gunakan pesan yang telah selesai sebagai riwayat pesan yang otoritatif.
Setel include_progress: false pada permintaan Pesan untuk menghilangkan hanya stream_progress. Peristiwa siklus hidup, ping, message_completed, galat, dan peristiwa terminal tetap dikirim jika relevan.
| Bidang | Deskripsi |
|---|---|
state | Status aktivitas: running, success, failed, atau skipped. Tangani nilai yang tidak dikenal dengan baik |
label | Label aktivitas yang mudah dibaca manusia |
Beberapa peristiwa progres dapat menyertakan url, file_name, atau server_name sebagai petunjuk tampilan opsional.
message_completed
Dikirim setiap kali sebuah Pesan selesai dan siap untuk diambil atau ditampilkan.
Ini adalah penanda batas, bukan objek Pesan lengkap. Ambil Pesan tersebut jika Anda memerlukan konten atau metadatanya.
event: message_completed
data: {"session_id":"ses_abc123","run_id":"run_abc123","message_id":"msg_abc123","sequence":4,"from":{"type":"agent","name":"my-support-agent"},"type":"external"}
| Bidang | Deskripsi |
|---|---|
message_id | ID Pesan yang telah selesai |
sequence | Nomor urut dalam Sesi |
from | Objek pengirim dengan type (user atau agent) dan name |
type | Jenis Pesan: external atau internal |
mcp_connection
Dikirim ketika agen membutuhkan pengguna akhir untuk menghubungkan atau mengotorisasi satu atau beberapa server MCP sebelum dapat melanjutkan. Peristiwa ini hanya tersedia dalam mode streaming.
| Bidang | Deskripsi |
|---|---|
connection_server_list | Server MCP yang memerlukan tindakan koneksi. Setiap server menyertakan mcp_server_id, mcp_server_name, dan auth_url opsional |
user_action_deadline_unix | Stempel waktu Unix saat tindakan pengguna koneksi berakhir |
mcp_connection_resolved
Dikirim ketika tindakan pengguna koneksi MCP telah diselesaikan atau telah kedaluwarsa.
Tidak ada bidang tambahan selain bidang umum yang berlingkup eksekusi.
warning
Dikirim untuk peringatan yang tidak fatal selama Eksekusi.
| Bidang | Deskripsi |
|---|---|
message | Peringatan tidak fatal yang mudah dibaca manusia |
code | Kode peringatan opsional |
stream_error
Dikirim saat sebuah Eksekusi gagal. Peristiwa stream_ended akhir dapat menyusul dengan success: false dan stop_reason: "error".
| Bidang | Deskripsi |
|---|---|
code | Kode Galat |
message | Pesan Galat yang mudah dibaca manusia |
stream_ended
Dikirim satu kali saat eksekusi selesai. Ini adalah Peristiwa terakhir untuk stream tersebut.
event: stream_ended
data: {"session_id":"ses_abc123","run_id":"run_abc123","success":true,"stop_reason":"end_run","usage":{"cost":"0.0032"}}
Contoh eksekusi yang dibatalkan:
event: stream_ended
data: {"session_id":"ses_abc123","run_id":"run_abc123","success":false,"stop_reason":"user_cancelled","usage":{"cost":"0.0012"}}
| Bidang | Deskripsi |
|---|---|
success | Apakah eksekusi berhasil diselesaikan |
stop_reason | Alasan akhir eksekusi: end_run, user_cancelled, user_action_timeout, atau error |
usage | Objek penggunaan untuk permintaan ini. cost selalu ada dan bernilai null jika biaya tidak tersedia |
ping
Frame keepalive yang dikirim setiap 15 detik untuk mencegah waktu tunggu proxy/CDN habis. Abaikan ini pada klien Anda.
Integrasi Server MCP
Hubungkan Agen Anda ke alat eksternal melalui Model Context Protocol (MCP):
- Server MCP yang dikelola Jenova: Server yang dihosting oleh Jenova untuk pencarian, pengambilan konten, pembuatan dokumen, dan kapabilitas bawaan lainnya
- Server MCP jarak jauh: Server MCP jarak jauh lainnya yang dikonfigurasi untuk Agen Anda
Server MCP harus dikonfigurasi di dasbor saat membuat atau mengedit Agen Anda. Untuk menggunakan server MCP Anda sendiri, tambahkan server tersebut ke Agen khusus, lalu panggil Agen tersebut melalui API. API akan menjalankan Alat yang diaktifkan dalam konfigurasi Agen; tidak diperlukan pengaturan tambahan dalam Permintaan API.
Saat sebuah Agen menggunakan Alat MCP selama respons, Peristiwa kemajuan dikirim dalam stream saat terjadi:
event: stream_progress
data: {"session_id":"ses_...","run_id":"run_...","state":"running","label":"Searching Google"}
Jika agen memerlukan pengguna akhir untuk menghubungkan atau mengotorisasi server MCP selama eksekusi, respons streaming dapat menyertakan peristiwa mcp_connection dan mcp_connection_resolved. Tampilkan daftar server koneksi kepada pengguna akhir Anda dan buka auth_url yang disediakan jika ada. Jaga agar stream SSE tetap terbuka selagi pengguna akhir menghubungkan atau mengotorisasi server tersebut.
Setelah otorisasi, Jenova menyimpan Token tersebut, jendela otorisasi menampilkan halaman penyelesaian, dan Eksekusi yang sama berlanjut secara otomatis. Pengguna Akhir tidak perlu mengirim ulang Pesan.
Jika pengguna akhir tidak menghubungkan, mengotorisasi, atau melewati atau membisukan sebelum user_action_deadline_unix, eksekusi berakhir dengan stop_reason: "user_action_timeout". Anda juga dapat membatalkan eksekusi yang aktif dengan POST /sessions/{session_id}/cancel.
Simpan auth_url di sisi klien. Jika klien terputus selama otorisasi, URL tetap berlaku hingga user_action_deadline_unix. Untuk permintaan yang persisten, periksa eksekusi dengan Dapatkan Status Eksekusi, atau ambil pesan setelah eksekusi selesai.
Permintaan non-streaming (stream: false) tidak mendukung tindakan pengguna koneksi MCP; gunakan streaming untuk agen yang mungkin memerlukan interaksi ini.
Lewati Koneksi MCP
POST /sessions/{session_id}/mcp/connection/skip
Mengabaikan tindakan pengguna koneksi MCP yang tertunda dan membiarkan eksekusi berlanjut tanpa koneksi tersebut.
Untuk membisukan prompt koneksi mendatang untuk satu server bagi pengguna akhir dan agen yang sama, sertakan mcp_server_id dan mute. mute menerima durasi seperti 30m, 24h, atau 7d, atau forever.
Isi Permintaan
| Bidang | Tipe | Wajib | Deskripsi |
|---|---|---|---|
run_id | string | Ya | ID eksekusi aktif dari peristiwa mcp_connection |
mcp_server_id | string | Tidak | Wajib jika menggunakan mute; gunakan mcp_server_id dari peristiwa tersebut |
mute | string | Tidak | Durasi seperti 30m, 24h, atau 7d, atau forever |
Respons 204 No Content
Stream memancarkan mcp_connection_resolved, kemudian eksekusi berlanjut dengan run_id yang sama.
Galat
| Status | Kode | Kondisi |
|---|---|---|
| 400 | invalid_payload | JSON tidak valid atau suatu bidang memiliki tipe yang tidak valid |
| 400 | bad_request | run_id tidak ada, tidak ada eksekusi aktif, atau tidak ada koneksi MCP untuk dilewati |
| 400 | bad_request | mute tidak valid, mcp_server_id tidak ada saat mute diatur, atau mcp_server_id tidak valid untuk sesi ini |
| 404 | session_not_found | Sesi tidak ada |
| 404 | session_not_owned | Sesi milik developer lain atau tidak sesuai dengan user yang diberikan |
| 409 | stale_run | run_id tidak cocok dengan Eksekusi aktif |
Penagihan
Semua Biaya dikurangkan dari saldo Kredit pengembang Anda. Lihat Penggunaan dan isi ulang Kredit di www.jenova.ai/platform.
Harga
| Operasi | Biaya |
|---|---|
| Create Session | $0,01 flat untuk setiap Sesi persisten yang dibuat oleh POST /sessions atau POST /messages |
| Fork Session | $0,05 flat, tanpa biaya pembuatan Sesi terpisah |
| Send Message | Bervariasi (lihat di bawah) |
| Invoke Model | Bervariasi, berdasarkan model dan token |
Biaya Pesan bergantung pada:
- Model - Model yang berbeda memiliki Biaya per-token yang berbeda
- Panjang konteks - Sesi yang lebih panjang mengonsumsi lebih banyak Token input per Permintaan
- Kompleksitas alur kerja - Alur kerja yang lebih panjang dan penggunaan Alat yang lebih berat (pencarian web, pembuatan berkas, analisis dokumen) meningkatkan total konsumsi Token
Biaya aktual dikembalikan sebagai stream_ended.usage.cost untuk Permintaan Streaming dan usage.cost untuk Permintaan JSON non-Streaming.
Penahanan Kredit
Setiap permintaan POST /messages, POST /sessions/{session_id}/messages, dan POST /invoke menempatkan penahanan $0,50 pada saldo Kredit Anda sebelum eksekusi dimulai. Ini mencadangkan dana untuk permintaan tersebut. Pesan yang mengantre dalam Eksekusi aktif (202 Accepted dengan status: "queued") tidak membuat penahanan tambahan; Penggunaan Eksekusi aktif diperiksa terhadap saldo Anda yang tersisa.
Saat permintaan selesai, penahanan diselesaikan sesuai Biaya aktual dan selisihnya dilepaskan. Jika Biaya aktual melebihi penahanan, selisihnya juga dikenakan, sehingga saldo Anda dapat menjadi di bawah nol. Permintaan yang dibatalkan dan gagal hanya dikenai Biaya untuk Penggunaan yang sudah terjadi. Jika Permintaan gagal sebelum mencapai Model, seluruh penahanan dilepaskan.
Karena adanya penahanan, saldo tersedia Anda mungkin terlihat lebih rendah untuk sementara selama Permintaan sedang berjalan. Anda memerlukan setidaknya $0,50 dalam saldo tersedia untuk permintaan POST /sessions/{session_id}/messages, POST /messages sementara (ephemeral), atau POST /invoke. Permintaan POST /messages persisten juga membuat sebuah Sesi dan memerlukan setidaknya $0,51 untuk menutupi penahanan ditambah biaya pembuatan Sesi.
Batas Kecepatan
Setiap akun pengembang dikenai tiga dimensi Batas Kecepatan:
| Dimensi | Default | Deskripsi |
|---|---|---|
| RPM (Requests Per Minute) | 200 | Jendela tetap 60 detik |
| RPD (Requests Per Day) | 10.000 | Jendela tetap 24 jam |
| Concurrent | 10 | Jumlah maksimum Permintaan yang berjalan secara bersamaan dan eksekusi aktif |
Sebuah eksekusi tetap menggunakan slot konkurennya sampai selesai, termasuk setelah respons 202 Accepted diberikan atau klien terputus. Permintaan POST /invoke tetap menggunakan slotnya sampai selesai, meskipun klien terputus.
Permintaan GET dan HEAD tidak mengonsumsi slot konkuren. cancel, undo, dan mcp/connection/skip juga tidak mengonsumsi slot konkuren, sehingga operasi ini tetap tersedia saat semua slot sedang digunakan. Permintaan ini tetap dihitung terhadap RPM dan RPD.
Batas per IP yang terpisah sebesar 1.200 permintaan per 60 detik juga berlaku untuk semua permintaan dan mengembalikan galat 429 rate_limit_exceeded yang sama.
Header Respons
Respons API yang terautentikasi menyertakan header batas kecepatan:
| Header | Deskripsi |
|---|---|
X-RateLimit-Limit | Batas RPM Anda |
X-RateLimit-Remaining | Permintaan yang tersisa dalam jendela satu menit saat ini |
X-RateLimit-Reset | Stempel waktu Unix saat jendela saat ini disetel ulang |
Retry-After | Detik yang harus ditunggu sebelum mencoba lagi. Dikirim pada respons 429 rate_limit_exceeded dan 503 write_freeze_active |
Ketika batas harian terlampaui, X-RateLimit-Limit, X-RateLimit-Remaining, dan X-RateLimit-Reset menggambarkan jendela harian sebagai gantinya.
Ketika batas terlampaui, API mengembalikan 429 Too Many Requests:
{
"error": {
"code": "rate_limit_exceeded",
"message": "Rate limit exceeded. Please try again later."
}
}
Penanganan Galat
Galat HTTP langsung dan galat eksekusi non-streaming mengikuti struktur yang konsisten:
{
"error": {
"code": "error_code_string",
"message": "Human-readable description"
}
}
Pesan galat dilokalkan berdasarkan lang atau Accept-Language (lihat Pelokalan).
Galat eksekusi streaming disampaikan sebagai peristiwa stream_error. Eksekusi yang gagal tetap dapat mengirimkan peristiwa stream_ended akhir dengan success: false dan stop_reason yang ditetapkan. Galat eksekusi non-streaming menyertakan objek usage tingkat atas; cost bernilai null jika biaya tidak tersedia.
Galat berikut dapat terjadi pada titik akhir mana pun:
| Status | Kode | Kondisi |
|---|---|---|
| 401 | invalid_api_key | Kunci API tidak ada, tidak valid, atau telah dicabut |
| 402 | developer_not_activated | Akun pengembang Anda belum diaktifkan. Beli kredit di dasbor untuk mengaktifkannya |
| 403 | developer_disabled | Akun pengembang Anda dinonaktifkan |
| 403 | forbidden | Permintaan dari jaringan ini diblokir |
| 413 | payload_too_large | Isi permintaan melebihi 1 MiB |
| 429 | rate_limit_exceeded | Batas kecepatan terlampaui. Lihat Batas Kecepatan |
| 503 | write_freeze_active | Permintaan tulis untuk sementara dinonaktifkan karena pemeliharaan |
Galat khusus titik akhir didokumentasikan langsung di bawah masing-masing titik akhir.
Galat Eksekusi Setelah Dimulai
Galat eksekusi muncul setelah permintaan pesan diterima. Dalam mode streaming, galat ini tampil sebagai peristiwa stream_error dan dapat diikuti oleh stream_ended dengan success: false. Dalam mode non-streaming, galat dikembalikan sebagai respons galat JSON dengan kode status HTTP di bawah ini.
| Kode Status HTTP Non-streaming | Kode | Kondisi |
|---|---|---|
| 400 | content_policy_violation | Penyedia model menolak permintaan karena alasan kebijakan konten |
| 400 | llm_context_limit_reached | Input melebihi jendela konteks model |
| 404 | session_not_found | Sesi dihapus sebelum eksekusi dapat dijalankan |
| 409 | busy | Sesi menjadi sibuk atau tidak tersedia sementara sebelum eksekusi dapat dimulai |
| 413 | total_image_size_exceeded | Gabungan payload gambar melebihi batas ukuran per permintaan pada model |
| 500 | internal_error | Kegagalan eksekusi yang tidak terduga |
| 500 | response_interrupted | Eksekusi terputus. Kirim ulang pesan tersebut |
| 500 | response_interrupted_message_saved | Eksekusi terputus setelah pesan Anda disimpan. Ambil pesan-pesan pada sesi tersebut sebelum mengirim ulang |
| 502 | llm_api_error | Galat pada penyedia model atau API model upstream |
| 502 | llm_empty_response | Model mengembalikan respons kosong |
| 502 | llm_reasoning_limit_reached | Model mencapai batas penalaran tanpa respons |
| 502 | llm_generation_limit_reached | Model mencapai batas generasi tanpa respons |
Paginasi
Daftar Sesi dan Daftar Pesan menggunakan paginasi berbasis cursor:
{
"items": [],
"next_cursor": "2026-05-19T11:15:00Z|ses_abc123",
"has_more": true
}
| Parameter | Tipe | Default | Maks | Deskripsi |
|---|---|---|---|---|
limit | integer | 20 | 100 | Jumlah item per halaman |
cursor | string | - | - | Cursor buram dari next_cursor sebelumnya |
Teruskan next_cursor sebagai parameter kueri cursor untuk mengambil halaman berikutnya, dengan melakukan URL-encoding pada nilainya. Ketika has_more bernilai false, tidak ada lagi hasil selanjutnya. limit di luar rentang 1-100 atau cursor yang tidak valid mengembalikan 400 bad_request.
Pelokalan
Semua titik akhir menerima parameter kueri lang yang opsional untuk mengatur bahasa pesan galat dan konten terlokalisasi lainnya.
| Sumber | Prioritas | Contoh |
|---|---|---|
Parameter kueri lang | Tertinggi | ?lang=zh |
Header Accept-Language | Cadangan | Accept-Language: ja |
| Default | Terendah | Bahasa Inggris (en) |
Anda dapat menambahkan ?lang=xx ke URL permintaan apa pun:
POST /sessions?lang=zh
GET /sessions/ses_abc123/messages?lang=ja
Bahasa yang didukung: en, zh, ja, ko, es, fr, de, it, pt, ru, id, th, vi
Privasi dan Data
Jenova tidak menggunakan prompt API, keluaran, riwayat percakapan, berkas yang diunggah, instruksi agen, atau basis pengetahuan untuk melatih model Jenova.
Untuk penyedia model pihak ketiga, Jenova menggunakan saluran API komersial, pengaturan akun, komitmen kontraktual, atau opsi keluar (opt-out) yang dimaksudkan untuk mencegah konten pelanggan digunakan untuk melatih model milik penyedia.
Jenova menyimpan dan memproses data API menggunakan infrastruktur A.S. Penyedia pihak ketiga dapat memproses data di jurisdiksi lain sebagaimana dijelaskan dalam Kebijakan Privasi dan Ketentuan Penggunaan.
Untuk detail lengkap, lihat Ketentuan Penggunaan, Kebijakan Privasi, dan Kebijakan Penggunaan.
Dukungan
- Dasbor: www.jenova.ai/platform
- Email: [email protected]