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

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 /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 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

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. Tidak mengembalikan ID sesi, tidak dapat dilanjutkan, dan datanya dihapus segera setelah permintaan selesai
streambooleanTidaktruetrue untuk streaming SSE, false untuk JSON. Otorisasi MCP mengharuskan streaming
include_progressbooleanTidaktrueSetel ke false untuk menghilangkan peristiwa stream_progress. Hanya untuk 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
additional_contextobject[]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

StatusKodeKondisi
400missing_required_fieldagent wajib diisi
400invalid_payloadJSON tidak valid atau suatu bidang memiliki tipe yang tidak valid
400bad_requestMode ephemeral tidak valid, additional_context tidak valid, atau user/session_name melebihi panjang maksimumnya
400content_or_uploaded_files_requiredcontent maupun file_urls tidak disediakan
400content_too_longIsi pesan melebihi 32.000 token
400exceed_max_upload_filesLebih dari 10 URL berkas yang berbeda 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_selectionmodel bukan ID model yang valid, atau model default agen tidak tersedia
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
include_progressbooleanTidaktrueSetel ke false untuk menghilangkan peristiwa stream_progress. Hanya untuk 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
additional_contextobject[]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

StatusKodeKondisi
400invalid_payloadJSON tidak valid atau suatu bidang memiliki tipe yang tidak valid
400bad_requestadditional_context tidak valid
400content_or_uploaded_files_requiredcontent maupun file_urls tidak disediakan
400content_too_longIsi Pesan melebihi 32.000 token
400exceed_max_upload_filesLebih dari 10 URL berkas yang berbeda 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_selectionmodel bukan ID Model yang valid, atau Model Sesi sudah tidak tersedia
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
409busySesi untuk sementara tidak tersedia karena pembaruan lain sedang berlangsung, atau additional_context dikirim saat Sesi memiliki Eksekusi aktif atau Pesan yang tertunda
429too_many_pendingSesi sudah memiliki 200 Pesan yang mengantre
503service_unavailableLayanan 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

StatusKodeKondisi
400bad_requestIdempotency-Key melebihi panjang maksimumnya
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 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

ParameterTipeDefaultMaksDeskripsi
limitinteger20100Jumlah Pesan per halaman
cursorstring--Kursor Paginasi
includestringexternal-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

BidangTipeDeskripsi
idstringID Pesan (berawalan msg_)
session_idstringID Sesi induk
sequenceintegerNomor urutan dalam Sesi. Nomor dapat digunakan kembali setelah Pesan dihapus
fromobjectObjek pengirim dengan type (user atau agent) dan name
typestringexternal untuk Pesan percakapan, atau internal untuk langkah kerja Agen
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. Lihat Objek File di bawah. Tidak disertakan pada Daftar Pesan dan Dapatkan Pesan jika Pesan tidak memiliki file
stop_reasonstringAda pada Pesan Agen eksternal yang memiliki konten. Nilainya adalah end_run
agentstringSlug Agen yang mengeksekusi, bila tersedia
agent_namestringNama tampilan Agen yang mengeksekusi, bila tersedia
progress_eventsarrayAktivitas yang tercatat untuk Pesan internal, bila tersedia. Setiap entri memiliki bidang yang sama dengan peristiwa stream_progress

Objek File

BidangTipeDeskripsi
file_idstringID file Jenova. Kosong bila tidak diketahui
namestringNama file
urlstringURL file. Kosong bila tidak diketahui
formatstringFormat file huruf kecil, seperti pdf, png, atau csv
sizeintegerUkuran file dalam byte. 0 bila tidak 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 berdasarkan ID.

Parameter Kueri

ParameterTipeDefaultDeskripsi
includestringexternalTipe Pesan yang dapat dikembalikan: external, internal, atau all

Respons 200 OK

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

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

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.

BidangTipeWajibDeskripsi
namestringYaHuruf kecil, angka, dan garis bawah, diawali huruf (maks. 64 karakter). Unik dalam satu permintaan, dengan mengabaikan garis bawah dan bentuk jamak
contentstringYaTeks konteks. Tidak boleh kosong (maks. 12.000 token)
BatasNilai
Maksimum item per Pesan4
Maksimum token per item12.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: ephemeral tidak diterima pada POST /sessions; gunakan POST /messages dengan ephemeral: true untuk permintaan sekali pakai.

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

Objek Sesi

BidangTipeDeskripsi
idstringID sesi (berawalan ses_)
session_namestringNama tampilan
agentstringSlug agen
agent_detailsobjectDetail agen dengan display_name. Hanya ada jika diminta dengan include=agent
userstringPengenal pengguna akhir. null jika sesi dibuat tanpa user
modelstringModel yang digunakan jika pesan tidak menentukan model. Disetel ke model default agen saat sesi dibuat. Kosong jika agen membiarkan Jenova memilih model
created_atstringStempel waktu ISO 8601
updated_atstringStempel waktu ISO 8601

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

ParameterTipeDefaultMaksDeskripsi
limitinteger20100Jumlah item per halaman
cursorstring--Kursor paginasi
userstring--Filter berdasarkan pengenal pengguna akhir (maks. 255 karakter)
agentstring--Filter berdasarkan slug agen
includestring--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

StatusKodeKondisi
400bad_requestParameter kueri tidak valid

Dapatkan Sesi

GET /sessions/{session_id}

Mengambil satu sesi berdasarkan ID.

Parameter Kueri

ParameterTipeDeskripsi
includestringSetel ke agent untuk menambahkan agent_details ke sesi

Respons 200 OK

Mengembalikan objek sesi.

Galat

StatusKodeKondisi
400bad_requestParameter kueri tidak valid
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
409busySesi 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

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

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
400invalid_payloadJSON tidak valid atau suatu bidang memiliki tipe yang tidak valid
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
400invalid_payloadJSON tidak valid atau suatu bidang memiliki tipe yang tidak valid
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 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

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

StatusKodeKondisi
400invalid_payloadJSON tidak valid atau suatu bidang memiliki tipe yang tidak valid
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 (opsional)

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
400invalid_payloadJSON tidak valid atau suatu bidang memiliki tipe yang tidak valid
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"
}

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

StatusKodeKondisi
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 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"
    }
  ]
}
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 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"
    }
  ]
}
BidangTipeDeskripsi
idstringIdentifikator model yang stabil. Teruskan ini sebagai nilai model pada Kirim Pesan atau Panggil Model
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 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

BidangTipeWajibDefaultDeskripsi
modelstringYa-ID model dari Daftar Model
contentstringYa-Prompt, termasuk instruksi apa pun
streambooleanTidaktruetrue untuk streaming SSE, false untuk JSON
userstringTidak-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

StatusKodeKondisi
400invalid_payloadJSON tidak valid atau suatu bidang memiliki tipe yang tidak valid
400missing_required_fieldcontent wajib diisi
400content_too_longKonten melebihi 32.000 token
400bad_requestuser melebihi panjang maksimumnya
400invalid_model_selectionmodel tidak ada atau bukan ID model yang valid
400content_policy_violationPenyedia model menolak permintaan karena alasan kebijakan konten
400llm_context_limit_reachedInput melebihi jendela konteks model
402insufficient_creditsKredit tidak cukup untuk memanggil model
500internal_errorGalat server yang tidak terduga
502llm_api_errorGalat pada penyedia model atau API model upstream
502llm_empty_responseModel mengembalikan respons kosong
502llm_reasoning_limit_reachedModel mencapai batas penalaran tanpa respons
502llm_generation_limit_reachedModel mencapai batas generasi tanpa respons
503service_unavailableLayanan 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:

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
idID 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.

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.

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.

BidangDeskripsi
stateStatus aktivitas: running, success, failed, atau skipped. 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":"my-support-agent"},"type":"external"}
BidangDeskripsi
message_idID Pesan yang telah selesai
sequenceNomor urut 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 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"}}
BidangDeskripsi
successApakah eksekusi berhasil diselesaikan
stop_reasonAlasan akhir eksekusi: end_run, user_cancelled, user_action_timeout, atau error
usageObjek 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

BidangTipeWajibDeskripsi
run_idstringYaID eksekusi aktif dari peristiwa mcp_connection
mcp_server_idstringTidakWajib jika menggunakan mute; gunakan mcp_server_id dari peristiwa tersebut
mutestringTidakDurasi 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

StatusKodeKondisi
400invalid_payloadJSON tidak valid atau suatu bidang memiliki tipe yang tidak valid
400bad_requestrun_id tidak ada, tidak ada eksekusi aktif, atau tidak ada koneksi MCP untuk dilewati
400bad_requestmute tidak valid, mcp_server_id tidak ada saat mute diatur, atau mcp_server_id tidak valid untuk sesi ini
404session_not_foundSesi tidak ada
404session_not_ownedSesi milik developer lain atau tidak sesuai 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 yang dibuat oleh POST /sessions atau POST /messages
Fork Session$0,05 flat, tanpa biaya pembuatan Sesi terpisah
Send MessageBervariasi (lihat di bawah)
Invoke ModelBervariasi, 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:

DimensiDefaultDeskripsi
RPM (Requests Per Minute)200Jendela tetap 60 detik
RPD (Requests Per Day)10.000Jendela tetap 24 jam
Concurrent10Jumlah 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:

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. 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:

StatusKodeKondisi
401invalid_api_keyKunci API tidak ada, tidak valid, atau telah dicabut
402developer_not_activatedAkun pengembang Anda belum diaktifkan. Beli kredit di dasbor untuk mengaktifkannya
403developer_disabledAkun pengembang Anda dinonaktifkan
403forbiddenPermintaan dari jaringan ini diblokir
413payload_too_largeIsi permintaan melebihi 1 MiB
429rate_limit_exceededBatas kecepatan terlampaui. Lihat Batas Kecepatan
503write_freeze_activePermintaan 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-streamingKodeKondisi
400content_policy_violationPenyedia model menolak permintaan karena alasan kebijakan konten
400llm_context_limit_reachedInput melebihi jendela konteks model
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
500response_interruptedEksekusi terputus. Kirim ulang pesan tersebut
500response_interrupted_message_savedEksekusi terputus setelah pesan Anda disimpan. Ambil pesan-pesan pada sesi tersebut sebelum mengirim ulang
502llm_api_errorGalat pada penyedia model atau API model upstream
502llm_empty_responseModel mengembalikan respons kosong
502llm_reasoning_limit_reachedModel mencapai batas penalaran tanpa respons
502llm_generation_limit_reachedModel 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
}
ParameterTipeDefaultMaksDeskripsi
limitinteger20100Jumlah item per halaman
cursorstring--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.

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