Jenova - Platform Agen AIPlatform API

Referensi API Agen Jenova

URL Dasar: https://api.jenova.ai/v1

Autentikasi: Bearer token di header Authorization


Daftar Isi


Gambaran Umum

Bangun dan jalankan agen AI yang siap untuk produksi tanpa harus merakit sendiri stack yang mendasarinya. Jenova Agent API menyatukan setiap kemampuan inti dalam satu layanan terkelola:

Stack Agen yang Lengkap

  • Orkestrasi Agen: Lapisan orkestrasi terpadu mengoordinasikan model, alat, memori, dan pengambilan data di berbagai alur kerja yang kompleks.
  • Memori & Konteks: Memori percakapan dan konteks tanpa batas terintegrasi di setiap sesi. Tidak diperlukan manajemen status eksternal.
  • Alat & MCP: Integrasi Alat tanpa batas dengan alat native platform maupun server MCP jarak jauh mana pun, siap digunakan langsung.
  • Gunakan Model Apa Pun: Berdayakan agen Anda dengan model dari OpenAI, Anthropic, Google, xAI, Qwen, dan lainnya melalui satu integrasi tunggal.
  • Penyimpanan Terkelola Penuh: Basis data relasional dan vektor terkelola dengan RAG terintegrasi. Tidak ada infrastruktur yang perlu disediakan atau diskalakan.
  • Kelas Produksi: Digunakan oleh ratusan ribu pengguna. Infrastruktur terkelola penuh, API yang stabil, dibangun untuk lalu lintas produksi.

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 tanpa penyimpanan, gunakan POST /messages dengan ephemeral: 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 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, 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.


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 atomik. Setel ephemeral: true untuk permintaan sekali pakai berbasis streaming tanpa penyimpanan yang tidak menyimpan riwayat sesi maupun pesan, tidak mengembalikan ID sesi, dan tidak dapat dilanjutkan.

Isi Permintaan

BidangTipeWajibDefaultDeskripsi
agentstringYa-Identifier slug agen
contentstringKondisional-Teks pesan. Wajib kecuali file_urls disediakan
file_urlsstring[]Kondisional-URL berkas yang akan dilampirkan. Wajib kecuali content disediakan
userstringTidak-Identifier pengguna akhir eksternal Anda (maksimal 255 karakter). Jika tidak disertakan, defaultnya adalah akun pengembang Anda
session_namestringTidak-Nama tampilan untuk sesi baru (maksimal 200 karakter)
ephemeralbooleanTidakfalsePermintaan sekali pakai berbasis streaming saja tanpa penyimpanan. Tidak menyimpan riwayat sesi maupun pesan, tidak mengembalikan ID sesi, dan tidak dapat dilanjutkan
streambooleanTidaktruetrue untuk streaming SSE, false untuk JSON. Otorisasi MCP mengharuskan streaming
modelstringTidak-Penggantian model satu kali khusus untuk permintaan ini saja. Gunakan ID model yang stabil seperti claude-sonnet-5. Tidak mengubah model default sesi

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 bentuk JSON pesan seperti yang ditunjukkan pada Lanjutkan Sesi, termasuk stop_reason dan usage untuk permintaan yang telah selesai.

Jika eksekusi tanpa streaming masih diproses setelah 90 detik, API mengembalikan 202 Accepted dengan status: "processing", session_id, run_id, dan message. 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

StatusKodeKondisi
400missing_required_fieldagent wajib diisi
400invalid_payloadJSON tidak valid atau suatu bidang memiliki tipe yang tidak valid
400bad_requestMode ephemeral tidak valid, atau user/session_name melebihi panjang maksimumnya
400content_or_uploaded_files_requiredcontent maupun file_urls tidak disediakan
400content_too_longIsi pesan melebihi panjang token maksimum
400exceed_max_upload_filesLebih dari 10 URL berkas dalam satu permintaan
400unsupported_file_formatSuatu URL berkas memiliki ekstensi berkas yang tidak didukung
400invalid_file_urlSuatu URL berkas tidak valid atau bukan HTTPS
400invalid_model_selectionPenggantian model bukan model produksi yang valid
402insufficient_creditsKredit tidak cukup untuk membuat sesi atau mengirim pesan
404agent_not_foundAgen 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

BidangTipeWajibDefaultDeskripsi
contentstringKondisional-Teks Pesan. Wajib kecuali file_urls disediakan
file_urlsstring[]Kondisional-URL berkas yang akan dilampirkan. Wajib kecuali content disediakan
streambooleanTidaktruetrue untuk streaming SSE, false untuk JSON. Otorisasi MCP memerlukan streaming
modelstringTidak-Penggantian Model satu kali khusus untuk permintaan ini saja. Gunakan ID Model yang stabil seperti claude-sonnet-5. Tidak mengubah Model default Sesi

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.

Galat

StatusKodeKondisi
400invalid_payloadJSON tidak valid atau suatu bidang memiliki tipe yang tidak valid
400content_or_uploaded_files_requiredcontent maupun file_urls tidak disediakan
400content_too_longIsi Pesan melebihi panjang token maksimum
400exceed_max_upload_filesLebih dari 10 URL berkas dalam satu Permintaan
400unsupported_file_formatSuatu URL berkas memiliki ekstensi berkas yang tidak didukung
400invalid_file_urlSuatu URL berkas tidak valid atau bukan HTTPS
400invalid_model_selectionPenggantian Model bukan Model produksi yang valid
402insufficient_creditsKredit tidak cukup untuk mengirim Pesan
404session_not_foundSesi tidak ditemukan
404session_not_ownedSesi milik developer lain atau tidak sesuai dengan user yang diberikan

Idempotensi

POST /messages dan POST /sessions/{session_id}/messages menerima header Idempotency-Key opsional. Gunakan kunci unik untuk setiap pengiriman pengguna logis agar percobaan ulang jaringan atau pengiriman ganda tidak membuat eksekusi duplikat.

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 200 atau 202 yang tersimpan dengan header Idempotent-Replayed: true.

Streaming: Stream tidak diputar ulang. Mencoba ulang saat sedang berjalan atau setelah selesai akan mengembalikan galat idempotensi dengan run_id asli dan, untuk permintaan yang persisten, session_id. Gunakan GET /sessions/{session_id}/runs/{run_id} untuk memeriksa eksekusi yang aktif, atau GET /sessions/{session_id}/messages untuk mengambil hasil yang telah tersimpan.

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

StatusKodeKondisi
409idempotency_key_reusedKunci yang sama digunakan dengan permintaan yang berbeda
409idempotency_key_in_usePermintaan asli masih berjalan
409idempotency_key_reusedPermintaan streaming asli sudah selesai dan tidak dapat diputar ulang

Daftar Pesan

GET /sessions/{session_id}/messages

Mengembalikan daftar Pesan percakapan yang terlihat dengan Paginasi. Halaman pertama berisi Pesan terbaru; dalam setiap halaman, Pesan diurutkan secara kronologis (yang paling lama lebih dulu). sequence adalah nomor urutan yang stabil dalam Sesi.

Parameter Kueri

ParameterTipeDefaultMaksDeskripsi
limitinteger20100Jumlah Pesan per halaman
cursorstring--Kursor Paginasi

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",
      "files": []
    }
  ],
  "next_cursor": "",
  "has_more": false
}

Objek Pesan

BidangTipeDeskripsi
idstringID Pesan (berawalan msg_)
session_idstringID Sesi induk
sequenceintegerNomor urutan yang stabil dalam Sesi
fromobjectObjek pengirim dengan type ("user" atau "agent") dan name
typestringTipe Pesan, biasanya external untuk Pesan percakapan yang terlihat
timestringStempel waktu ISO 8601
contentstringKonten teks. Ada pada Pesan eksternal
modelstringID Model stabil yang menghasilkan respons. Hanya ada pada Pesan Agen
filesarrayFile yang dilampirkan atau dihasilkan yang disertakan dengan Pesan. Setiap entri mencakup file_id, name, url, format, dan size bila diketahui
stop_reasonstringAda pada Pesan Agen yang telah selesai. Nilai saat ini adalah end_run
agentstringSlug Agen yang mengeksekusi, bila tersedia
agent_namestringNama tampilan Agen yang mengeksekusi, bila tersedia

Objek File

BidangTipeDeskripsi
file_idstringID file Jenova, bila tersedia
namestringNama file
urlstringURL file, bila tersedia
formatstringFormat file huruf kecil, seperti pdf, png, atau csv
sizeintegerUkuran file dalam byte, bila diketahui

Galat

StatusKodeKondisi
400bad_requestParameter kueri tidak valid
404session_not_foundSesi tidak ada
404session_not_ownedSesi milik developer lain atau tidak sesuai dengan user yang diberikan

Dapatkan Pesan

GET /sessions/{session_id}/messages/{message_id}

Mengambil satu Pesan yang terlihat berdasarkan ID.

Respons 200 OK

Mengembalikan satu objek Pesan dengan struktur yang sama seperti respons daftar.

Galat

StatusKodeKondisi
404session_not_foundSesi tidak ada
404session_not_ownedSesi milik developer lain atau tidak sesuai dengan user yang diberikan
404not_foundPesan tidak ada dalam Sesi ini

Lampiran File

Berikan URL HTTPS yang dapat diakses publik pada bidang file_urls.

BatasNilai
Maksimum file per Pesan10
Ukuran file maksimum20 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

Saat mendaftar Pesan, file yang dilampirkan muncul dalam array files pada Pesan tersebut.


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: ephemeral tidak diterima pada POST /sessions; gunakan POST /messages dengan ephemeral: true untuk permintaan satu kali tanpa penyimpanan.

Isi Permintaan

BidangTipeWajibDeskripsi
agentstringYaPengenal slug agen
userstringTidakPengenal pengguna akhir eksternal Anda (maks. 255 karakter). Jika dihilangkan, defaultnya adalah akun developer Anda
session_namestringTidakNama 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"
}

Galat

StatusKodeKondisi
400invalid_payloadJSON tidak valid atau suatu bidang memiliki tipe yang tidak valid
400missing_required_fieldagent diwajibkan
400bad_requestephemeral disertakan, atau user/session_name melebihi panjang maksimumnya
402insufficient_creditsKredit tidak cukup untuk membuat sesi
404agent_not_foundAgen 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

ParameterTipeDeskripsi
limitintegerJumlah item per halaman (default 20, maks. 100)
cursorstringKursor paginasi
userstringFilter berdasarkan pengenal pengguna akhir (maks. 255 karakter)
agentstringFilter berdasarkan slug agen

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": "eyJ2IjoxLCJrIjoiY3VyXzAxIn0",
  "has_more": true
}

Galat

StatusKodeKondisi
400bad_requestParameter kueri tidak valid

Dapatkan Sesi

GET /sessions/{session_id}

Mengambil satu sesi berdasarkan ID.

Respons 200 OK

Mengembalikan objek sesi dengan struktur yang sama dengan respons pembuatan.

Galat

StatusKodeKondisi
404session_not_foundSesi tidak ada
404session_not_ownedSesi 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

BidangTipeWajibDeskripsi
session_namestringYaNama tampilan baru (maksimal 200 karakter)

Respons 200 OK

Mengembalikan objek sesi yang telah diperbarui.

Galat

StatusKodeKondisi
400invalid_payloadJSON tidak valid atau suatu bidang memiliki tipe yang tidak valid
400missing_required_fieldsession_name wajib diisi
400bad_requestsession_name melebihi panjang maksimalnya
404session_not_foundSesi tidak ada
404session_not_ownedSesi dimiliki oleh developer lain atau tidak cocok dengan user yang diberikan

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

StatusKodeKondisi
404session_not_foundSesi tidak ada
404session_not_ownedSesi dimiliki oleh developer lain atau tidak cocok dengan user yang diberikan
409busySesi 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 Pembatalan; 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 sedang berlangsung saat ini. Ini tidak menghapus pesan yang sudah selesai sebelum pembatalan.

Isi Permintaan

BidangTipeWajibDeskripsi
run_idstringTidakPenjaga eksekusi kedaluwarsa opsional. Jika diberikan dan tidak cocok dengan eksekusi yang aktif, API mengembalikan 409 stale_run

Respons 204 No Content

Galat

StatusKodeKondisi
400cancel_not_allowedTidak ada eksekusi aktif untuk dibatalkan, atau pembatalan tidak diizinkan
404session_not_foundSesi tidak ada
404session_not_ownedSesi dimiliki oleh developer lain atau tidak cocok dengan user yang diberikan
409stale_runrun_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

BidangTipeWajibDeskripsi
run_idstringTidakPenjaga 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

StatusKodeKondisi
400cancel_not_allowedTidak ada eksekusi aktif untuk diurungkan, atau pembatalan tidak diizinkan
404session_not_foundSesi tidak ada
404session_not_ownedSesi dimiliki oleh developer lain atau tidak cocok dengan user yang diberikan
409stale_runrun_id yang diberikan tidak cocok dengan eksekusi yang aktif
409busySesi untuk sementara tidak tersedia karena pembaruan lain sedang berlangsung

Hapus Pesan Terbaru

POST /sessions/{session_id}/messages/delete

Menghapus N pesan terbaru dari sesi yang sedang idle. Sesi tidak boleh memiliki eksekusi yang aktif.

Isi Permintaan

BidangTipeWajibDeskripsi
countintegerYaJumlah pesan terbaru yang akan dihapus dari akhir (harus lebih besar dari 0)

Respons 200 OK

{
  "deleted": ["msg_002", "msg_001"]
}

Galat

StatusKodeKondisi
400bad_requestcount tidak ada, nol, atau negatif; atau tidak ada pesan untuk dihapus
404session_not_foundSesi tidak ada
404session_not_ownedSesi milik developer lain atau tidak cocok dengan user yang diberikan
409busySesi 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

BidangTipeWajibDeskripsi
message_idstringTidakID 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

StatusKodeKondisi
400bad_requestmessage_id tidak valid
402insufficient_creditsKredit tidak cukup untuk melakukan fork sesi
404not_foundmessage_id tidak ada dalam sesi ini
404session_not_foundSesi tidak ada
404session_not_ownedSesi milik developer lain atau tidak cocok dengan user yang diberikan
409busySesi 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"
}

Respons juga dapat mencakup petunjuk kemajuan terbaru selama eksekusi masih aktif.

Galat

StatusKodeKondisi
400bad_requestSesi bersifat ephemeral
404session_not_foundSesi tidak ada
404session_not_ownedSesi milik developer lain atau tidak cocok dengan user yang diberikan
404not_foundEksekusi 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 Kunci API 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"
    }
  ]
}
BidangTipeDeskripsi
agentstringSlug agen yang stabil untuk diteruskan sebagai nilai agent
display_namestringNama tampilan yang mudah dibaca manusia
descriptionstringDeskripsi agen

Model

Daftar Model

GET /models

Mengembalikan semua model yang tersedia untuk digunakan pada bidang model saat mengirim pesan.

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": "kimi-k2.6",
      "name": "Kimi K2.6",
      "thinking_variant": "kimi-k2.6-thinking"
    }
  ]
}
BidangTipeDeskripsi
idstringIdentifikator model yang stabil. Teruskan ini sebagai nilai model pada Send Message
namestringNama tampilan yang mudah dibaca manusia
thinking_variantstringID 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 default agen akan digunakan.


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 60 menit. Permintaan non-streaming menunggu hingga 90 detik, kemudian mengembalikan 202 Accepted sementara eksekusi terus berlangsung.

Header Koneksi

Respons SSE 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.

Sambungkan Ulang dan Pemulihan

Stream SSE tidak diulang (replay). Jika koneksi terputus, 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 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 List Messages.

Bidang umum pada peristiwa yang berlingkup eksekusi:

BidangDeskripsi
session_idID Sesi. Dihilangkan untuk stream efemeral. Catat nilai ini dari stream_started untuk permintaan lanjutan saat menggunakan POST /messages persisten
run_idID Eksekusi saat ini, jika tersedia

stream_started

Dikirim sekali saat Eksekusi dimulai.

BidangDeskripsi
agentSlug 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}
BidangDeskripsi
chunk_contentPotongan teks
seqUrutan 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.

BidangDeskripsi
contentPotongan 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.

Lanjutan: permintaan Pesan menerima include_progress: false untuk menghilangkan hanya stream_progress. Peristiwa siklus hidup, ping, message_completed, galat, dan peristiwa terminal tetap dikirim jika relevan.

BidangDeskripsi
stateStatus siklus hidup: running, in-progress, success, failed, skipped, complete, cancelled, antara lain. Tangani nilai yang tidak dikenal dengan baik
labelLabel 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":"Jenova"},"type":"external"}
BidangDeskripsi
message_idID Pesan yang telah selesai
sequenceNomor urut yang stabil dalam Sesi
fromObjek pengirim dengan type (user atau agent) dan name
typeJenis 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.

BidangDeskripsi
connection_server_listServer MCP yang memerlukan tindakan koneksi. Setiap server menyertakan mcp_server_id, mcp_server_name, dan auth_url opsional
user_action_deadline_unixStempel 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.

BidangDeskripsi
messagePeringatan tidak fatal yang mudah dibaca manusia
codeKode peringatan opsional

stream_error

Dikirim saat sebuah Eksekusi gagal. Peristiwa stream_ended akhir dapat menyusul dengan success:false dan stop_reason:"error".

BidangDeskripsi
codeKode Galat
messagePesan 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 kegagalan:

event: stream_ended
data: {"session_id":"ses_abc123","run_id":"run_abc123","success":false,"stop_reason":"user_cancelled","usage":{"cost":"0.0012"}}
BidangDeskripsi
successApakah eksekusi berhasil diselesaikan
stop_reasonAlasan akhir eksekusi: end_run, user_cancelled, user_action_timeout, atau error
usageObjek penggunaan untuk permintaan ini. Saat ini menyertakan cost jika 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 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, 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, sambungkan kembali dengan Get Run Status, 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 API yang sama, sertakan mcp_server_id dan mute. Nilai yang didukung adalah 24h dan forever.

Isi Permintaan

BidangTipeWajibDeskripsi
run_idstringYaID eksekusi aktif dari peristiwa mcp_connection
mcp_server_idstringTidakWajib jika menggunakan mute; gunakan mcp_server_id dari peristiwa tersebut
mutestringTidak24h atau forever

Respons 204 No Content

Stream memancarkan mcp_connection_resolved, kemudian eksekusi berlanjut dengan run_id yang sama.

Galat

StatusKodeKondisi
400bad_requestrun_id tidak ada, tidak ada eksekusi aktif, atau tidak ada koneksi MCP untuk dilewati
400bad_requestmute tidak valid, atau mcp_server_id tidak ada saat mute diatur
404session_not_foundSesi tidak ada
404session_not_ownedTidak cocok dengan user yang diberikan
409stale_runrun_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

OperasiBiaya
Create Session$0,01 flat untuk setiap Sesi persisten, termasuk Sesi yang dibuat secara implisit oleh POST /messages
Fork Session$0,05 flat
Send MessageBervariasi (lihat di bawah)

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 Eksekusi Pesan baru menempatkan penahanan $0,50 pada saldo Kredit Anda sebelum eksekusi dimulai. Ini mencadangkan dana untuk Eksekusi tersebut. Pesan susulan yang mengantre dalam Eksekusi aktif tidak membuat penahanan tambahan; Penggunaan Eksekusi aktif diperiksa terhadap saldo Anda yang tersisa.

Saat Eksekusi selesai, penahanan diselesaikan sesuai Biaya aktual dan selisihnya dilepaskan. Eksekusi yang dibatalkan dan gagal hanya dikenai Biaya untuk Penggunaan yang sudah terjadi. Jika Permintaan gagal sebelum mencapai Model, seluruh penahanan dilepaskan.

Ini berarti saldo tersedia Anda mungkin terlihat lebih rendah untuk sementara selama Permintaan sedang berjalan. Anda memerlukan setidaknya $0,50 dalam saldo tersedia untuk mengirim Pesan ke Sesi yang sudah ada atau untuk mengirim Pesan sementara (ephemeral). Permintaan POST /messages persisten pertama membuat sebuah Sesi dan memerlukan setidaknya $0,51 untuk menutupi penahanan Pesan ditambah biaya pembuatan Sesi.


Batas Kecepatan

Setiap akun pengembang dikenai tiga dimensi Batas Kecepatan:

DimensiDefaultDeskripsi
RPM (Requests Per Minute)60Jendela tetap per menit
RPD (Requests Per Day)1.000Jendela tetap per hari
Concurrent5Jumlah maksimum Permintaan yang berjalan secara bersamaan

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.

Header Respons

Respons API yang terautentikasi menyertakan header batas kecepatan:

HeaderDeskripsi
X-RateLimit-LimitBatas RPM Anda
X-RateLimit-RemainingPermintaan yang tersisa dalam jendela satu menit saat ini
X-RateLimit-ResetStempel waktu Unix saat jendela saat ini disetel ulang
Retry-AfterDetik yang harus ditunggu sebelum mencoba lagi (hanya pada 429)

Ketika batas terlampaui, API mengembalikan 429 Too Many Requests:

{
  "error": {
    "code": "rate_limit_exceeded",
    "message": "Rate limit exceeded. Please retry after 12 seconds."
  }
}

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 parameter lang (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 juga dapat menyertakan objek usage tingkat atas ketika data biaya tersedia.

Galat khusus titik akhir didokumentasikan langsung di bawah masing-masing titik akhir.

Galat Eksekusi Setelah Dimulai

Galat eksekusi muncul setelah eksekusi pesan telah dimulai. 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-streamingKodeDeskripsi
400content_policy_violationPenyedia model menolak permintaan karena alasan kebijakan konten
404session_not_foundSesi dihapus sebelum eksekusi dapat dijalankan
409busySesi menjadi sibuk atau tidak tersedia sementara sebelum eksekusi dapat dimulai
413total_image_size_exceededGabungan payload gambar melebihi batas ukuran per permintaan pada model
500internal_errorKegagalan eksekusi yang tidak terduga
502llm_api_errorGalat pada penyedia model atau API model upstream

Paginasi

Titik akhir daftar menggunakan paginasi berbasis cursor:

{
  "items": [],
  "next_cursor": "eyJ2IjoxLCJrIjoiY3VyXzAyIn0",
  "has_more": true
}
ParameterTipeDefaultMaksDeskripsi
limitinteger20100Jumlah item per halaman
cursorstring--Cursor buram dari next_cursor sebelumnya

Teruskan next_cursor sebagai parameter kueri cursor untuk mengambil halaman berikutnya. Ketika has_more bernilai false, tidak ada lagi hasil selanjutnya.


Pelokalan

Semua titik akhir menerima parameter kueri lang yang opsional untuk mengatur bahasa pesan galat dan konten terlokalisasi lainnya.

SumberPrioritasContoh
Parameter kueri langTertinggi?lang=zh
Header Accept-LanguageCadanganAccept-Language: ja
DefaultTerendahBahasa 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