Jenova - แพลตฟอร์มเอเจนต์ AIแพลตฟอร์ม API

เอกสารอ้างอิง API เอเจนต์ Jenova

URL พื้นฐาน: https://api.jenova.ai/v1

การยืนยันตัวตน: Bearer token ใน Authorization header


สารบัญ


ภาพรวม

รันเอเจนต์แบบกำหนดเองในผลิตภัณฑ์หรือเวิร์กโฟลว์ของคุณได้ในไม่กี่นาที ตั้งค่าเอเจนต์ของคุณสำหรับงานใดก็ได้ เลือกโมเดลและเครื่องมือที่ต้องการ แล้วปล่อยให้ Jenova ดูแลเอเจนต์ harness ฐานข้อมูล และการขยายขนาด

สแต็กเอเจนต์แบบครบวงจร:

  • เอเจนต์ harness แบบมีผู้ดูแล: ส่งคำขอหนึ่งครั้ง รับงานที่เสร็จสมบูรณ์ เอเจนต์ของคุณจะค้นคว้า ให้เหตุผล เรียกใช้เครื่องมือ และสร้างไฟล์ให้ครบ — ตรงตามที่คุณกำหนด
  • คอนเท็กซ์และหน่วยความจำไม่จำกัด: การจัดการคอนเท็กซ์ที่ขับเคลื่อนด้วย RAG และการติดตามสถานะเซสชันเฉพาะของ Jenova ช่วยให้มีหน่วยความจำไม่จำกัดภายในบทสนทนา
  • คลังเครื่องมือและ MCP: เชื่อมต่อกับคลังเครื่องมือ 30+ รายการและเซิร์ฟเวอร์ MCP ของเรา เช่น การค้นหา การสร้างรูปภาพ อีเมล และอื่น ๆ — หรือเสียบเซิร์ฟเวอร์ MCP ของคุณเองเข้าไป
  • สลับไปยังโมเดลใดก็ได้อย่างราบรื่น: นำโมเดลจาก OpenAI, Anthropic, Google, xAI หรือผู้ให้บริการโอเพนซอร์สชั้นนำไปใช้งาน และสลับระหว่างโมเดลเหล่านั้นได้ด้วยพารามิเตอร์เดียว
  • ความรู้และ RAG แบบมีผู้ดูแล: Jenova จัดการไปป์ไลน์ RAG แบบ end-to-end — การแบ่งเนื้อหาเป็นชิ้นย่อย การทำดัชนี การจัดเก็บ และการค้นคืน
  • พิสูจน์แล้วในงานขนาดใหญ่: ใช้งานบนโครงสร้างพื้นฐานที่ผ่านสมรภูมิมาแล้ว ซึ่งรันเอเจนต์ที่ทำงานอยู่จริงในโปรดักชันหลายร้อยตัว โดยที่คุณไม่ต้องจัดเตรียม ขยายขนาด หรือดูแลคลัสเตอร์แม้แต่ตัวเดียว

เริ่มต้นใช้งานอย่างรวดเร็ว

1. รับคีย์ API ของคุณ

สร้างคีย์ API จากแดชบอร์ดสำหรับนักพัฒนาที่ www.jenova.ai/platform คีย์จะมีรูปแบบ jnv_sk_* และถูกส่งในรูปแบบ Bearer token

2. เลือกหรือสร้างเอเจนต์

เลือกเอเจนต์ที่สร้างไว้ล่วงหน้าจากแพลตฟอร์ม หรือสร้างเอเจนต์แบบกำหนดเองในแดชบอร์ด พร้อมคำสั่ง การตั้งค่าโมเดล ไฟล์ฐานความรู้ เครื่องมือ และเซิร์ฟเวอร์ MCP

3. ส่งข้อความแรกของคุณ

สร้างเซสชันและส่งข้อความในการเรียกครั้งเดียว:

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

การตอบกลับจะถูกสตรีมกลับมาในรูปแบบ 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"}}

บันทึกค่า session_id จาก stream_started เพื่อใช้ในคำขอต่อไป สำหรับการตอบกลับแบบ JSON แบบซิงโครนัส ดู ส่งข้อความ


แนวคิดหลัก

เอเจนต์

เอเจนต์ AI ที่คุณโต้ตอบด้วยผ่าน API เอเจนต์แต่ละตัวมี slug ที่ไม่ซ้ำกัน (เช่น my-support-agent) ซึ่งใช้เป็นค่า agent ในการเรียก API

  • สร้างไว้ล่วงหน้า: เลือกจากเอเจนต์ที่มีอยู่แล้วบนแพลตฟอร์ม
  • กำหนดเอง: กำหนดค่าเอเจนต์ของคุณเองในแดชบอร์ด พร้อมคำสั่ง โมเดล ฐานความรู้ เครื่องมือ และเซิร์ฟเวอร์ MCP

เซสชัน

เธรดการสนทนาที่เป็นอิสระระหว่างผู้ใช้ปลายทางและเอเจนต์

  • ตัวระบุ: ID ที่มีคำนำหน้า (เช่น ses_abc123)
  • ขอบเขต: สามารถมีหลายเซสชันสำหรับเอเจนต์และผู้ใช้ปลายทางเดียวกันได้ โดยแต่ละเซสชันมีสถานะการสนทนาที่เป็นอิสระ
  • วงจรชีวิต: เซสชันจะคงอยู่อย่างไม่มีกำหนดจนกว่าจะถูกลบผ่าน API สำหรับงานแบบครั้งเดียวที่ไม่จำเป็นต้องใช้เซสชัน ให้ใช้ POST /messages พร้อม ephemeral: true
  • การแยกแพลตฟอร์ม: เซสชันของ API แยกออกจากการสนทนาในเว็บแอป Jenova ผู้ใช้ปลายทาง ประวัติเซสชัน และการเรียกเก็บเงินเป็นอิสระต่อกันระหว่าง API และเว็บแอป

ข้อความ

รายการเดียวในประวัติการสนทนาของเซสชัน ซึ่งส่งกลับโดยจุดเชื่อมต่อ ข้อความ ข้อความแต่ละรายการมีอ็อบเจ็กต์ from ที่มีโครงสร้าง ประกอบด้วย type (user หรือ agent) และ name รวมถึง type ของข้อความ:

  • external - ข้อความในการสนทนาที่ตั้งใจให้แสดงเป็นเนื้อหาแชท
  • internal - ข้อความไม่บังคับที่แสดงถึงขั้นตอนการทำงานของเอเจนต์ระหว่างการรัน เช่น การเรียกใช้เครื่องมือหรือการค้นคืนข้อมูล

การรัน

การทำงานของเอเจนต์เพียงครั้งเดียวที่ถูกสร้างขึ้นเมื่อคุณส่งข้อความ การรันหนึ่งครั้งจะมี run_id อาจสตรีมอีเวนต์ระหว่างที่กำลังทำงานอยู่ และอาจสร้างข้อความที่เสร็จสมบูรณ์อย่างน้อยหนึ่งรายการ แต่ละเซสชันสามารถมีการรันที่กำลังทำงานอยู่ได้เพียงหนึ่งครั้งในเวลาเดียวกัน

ผู้ใช้ปลายทาง

ฟิลด์ user กำหนดขอบเขตของเซสชันให้กับผู้ใช้ปลายทางในแอปพลิเคชันของคุณ ใช้ ID ที่คงที่และไม่มีความหมายในตัวเอง (opaque) เช่น ID ผู้ใช้ภายในของคุณหรือ UUID หลีกเลี่ยงการใช้อีเมลหรือ PII อื่น ๆ เว้นแต่แอปพลิเคชันของคุณจำเป็นต้องใช้ เซสชันที่สร้างด้วยค่า user เดียวกันจะถูกจัดกลุ่มเข้าด้วยกัน ทำให้สามารถแสดงรายการเซสชันตามผู้ใช้แต่ละรายได้

หากไม่ระบุ user เซสชันจะถูกกำหนดขอบเขตให้กับบัญชีนักพัฒนาของคุณ และจะไม่สามารถกรองตามผู้ใช้ปลายทางได้ในภายหลัง ให้ส่ง user เสมอในสภาพแวดล้อมที่ใช้งานจริง

สำหรับคำขอเกี่ยวกับเซสชันที่มีอยู่แล้ว (จุดเชื่อมต่อใดๆ ที่มี {session_id} อยู่ในพาธ) user เป็นตัวป้องกันความเป็นเจ้าของที่ไม่บังคับ หากคุณระบุค่านี้ ค่าดังกล่าวต้องตรงกับค่า user ที่ใช้ตอนสร้างเซสชัน มิฉะนั้น API จะส่งกลับ 404 session_not_owned ให้ส่งค่านี้เป็นพารามิเตอร์คิวรีในคำขอ GET และ DELETE และส่งในเนื้อหา JSON สำหรับคำขอ POST และ PATCH หากส่ง user เป็นพารามิเตอร์คิวรีในคำขอ POST หรือ PATCH จะได้รับ 400 bad_request


การยืนยันตัวตน

ยืนยันตัวตนทุกคำขอด้วย Bearer token ในส่วนหัว Authorization:

Authorization: Bearer jnv_sk_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

คีย์ API ถูกสร้างขึ้นจากแดชบอร์ดสำหรับนักพัฒนา

User-Agent เป็นทางเลือกไม่บังคับ SDK อาจตั้งค่านี้เพื่อการวินิจฉัย แต่ API ไม่จำเป็นต้องใช้

รูปแบบคีย์: คีย์เริ่มต้นด้วยพรีฟิกซ์ jnv_sk_ ตามด้วยสตริงสุ่มที่เข้ารหัสแบบ base62

ขีดจำกัด: บัญชีนักพัฒนาแต่ละบัญชีสามารถมี คีย์ API ที่ใช้งานอยู่ได้สูงสุด 10 คีย์


จุดเชื่อมต่อ API

API ข้อความ

การส่งข้อความคือเส้นทาง API หลัก ใช้ POST /messages สำหรับข้อความแรก ซึ่งจะสร้างเซสชันและเริ่มการรันในคำขอเดียว ใช้ POST /sessions/{session_id}/messages เมื่อดำเนินการต่อจาก session_id ที่บันทึกไว้

ส่งข้อความ

POST /messages

สร้างเซสชันแบบถาวรและส่งข้อความแรกในคำขอเดียว กำหนด ephemeral: true สำหรับคำขอแบบครั้งเดียวที่สตรีม ซึ่งจะไม่ส่งกลับ session ID และไม่สามารถดำเนินการต่อได้ ข้อมูลของคำขอจะถูกลบไม่นานหลังจากคำขอเสร็จสมบูรณ์

เนื้อหาคำขอ

ฟิลด์ประเภทจำเป็นค่าเริ่มต้นคำอธิบาย
agentstringใช่-slug ที่ระบุตัวตนของเอเจนต์
contentstringตามเงื่อนไข-ข้อความ จำเป็นต้องระบุ เว้นแต่มีการระบุ file_urls
file_urlsstring[]ตามเงื่อนไข-URL ของไฟล์ที่จะแนบ จำเป็นต้องระบุ เว้นแต่มีการระบุ content
userstringไม่-ตัวระบุผู้ใช้ปลายทางภายนอกของคุณ (สูงสุด 255 ตัวอักษร) หากไม่ระบุ จะใช้ค่าเริ่มต้นเป็นบัญชีนักพัฒนาของคุณ
session_namestringไม่-ชื่อที่แสดงสำหรับเซสชันใหม่ (สูงสุด 200 ตัวอักษร)
ephemeralbooleanไม่falseคำขอแบบครั้งเดียวที่สตรีมอย่างเดียว ไม่ส่งกลับ session ID ไม่สามารถดำเนินการต่อได้ และข้อมูลจะถูกลบไม่นานหลังจากคำขอเสร็จสมบูรณ์
streambooleanไม่truetrue สำหรับการสตรีมแบบ SSE, false สำหรับ JSON การอนุญาตสิทธิ์ของ MCP ต้องใช้การสตรีม
include_progressbooleanไม่trueกำหนดเป็น false เพื่อละเว้นอีเวนต์ stream_progress ใช้กับการสตรีมเท่านั้น
modelstringไม่-การกำหนดโมเดลแทนที่แบบครั้งเดียวสำหรับคำขอนี้เท่านั้น ใช้ ID โมเดลที่มั่นคง เช่น claude-sonnet-5 ไม่เปลี่ยนแปลงโมเดลเริ่มต้นของเซสชัน
additional_contextobject[]ไม่-บริบทที่มีชื่อสำหรับคำขอนี้เท่านั้น ดู บริบทเพิ่มเติม

ตัวอย่าง - การสตรีม (ค่าเริ่มต้น)

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

การตอบกลับเป็นสตรีม SSE (ดู การสตรีม (SSE) สำหรับรูปแบบอีเวนต์) คำขอแบบถาวรจะรวม session_id ใหม่ ส่วนคำขอ ephemeral: true จะไม่มี session_id และต้องใช้การสตรีม

ตัวอย่าง - JSON (ไม่สตรีม)

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

การตอบกลับ

การตอบกลับแบบสตรีมจะส่งอีเวนต์ SSE ตามที่ระบุไว้ใน การสตรีม (SSE) การตอบกลับแบบไม่สตรีมจะส่งกลับ อ็อบเจ็กต์ข้อความ พร้อม stop_reason และ usage สำหรับคำขอ ตามที่แสดงไว้ใน ดำเนินเซสชันต่อ stop_reason จะเป็น end_run หรือ user_cancelled หากการรันถูกยกเลิกหลังจากที่เอเจนต์สร้างข้อความแล้ว

หากการรันถูกยกเลิกก่อนที่เอเจนต์จะสร้างข้อความ API จะส่งกลับ 200 OK พร้อมด้วย status: "cancelled", session_id, run_id, stop_reason: "user_cancelled" และ usage

หากการรันแบบไม่สตรีมยังอยู่ในระหว่างประมวลผลหลังจาก 90 วินาที API จะส่งกลับ 202 Accepted พร้อมด้วย status: "processing", session_id, run_id และ message ที่เป็นข้อความสำหรับมนุษย์อ่าน การรันจะดำเนินต่อไปหลังจากการตอบกลับหรือการตัดการเชื่อมต่อของไคลเอนต์ ตรวจสอบข้อความของเซสชัน หรือใช้การสตรีมสำหรับกระบวนการทำงานที่ยาวขึ้น

ข้อผิดพลาด

สถานะรหัสเงื่อนไข
400missing_required_fieldต้องระบุ agent
400invalid_payloadJSON มีรูปแบบไม่ถูกต้อง หรือฟิลด์มีประเภทข้อมูลไม่ถูกต้อง
400bad_requestโหมด ephemeral ไม่ถูกต้อง, additional_context ไม่ถูกต้อง หรือ user/session_name เกินความยาวสูงสุด
400content_or_uploaded_files_requiredไม่มีการระบุทั้ง content และ file_urls
400content_too_longเนื้อหาข้อความเกิน 32,000 token
400exceed_max_upload_filesมี URL ไฟล์ที่แตกต่างกันมากกว่า 10 รายการในคำขอเดียว
400unsupported_file_formatURL ไฟล์มีนามสกุลไฟล์ที่ไม่รองรับ
400invalid_file_urlURL ไฟล์มีรูปแบบไม่ถูกต้อง หรือไม่ใช่ HTTPS
400invalid_model_selectionmodel ไม่ใช่ ID โมเดลที่ถูกต้อง หรือโมเดลเริ่มต้นของเอเจนต์ไม่พร้อมใช้งาน
402insufficient_creditsเครดิตไม่พอสำหรับการสร้างเซสชันหรือส่งข้อความ
404agent_not_foundเอเจนต์ไม่มีอยู่ หรือบัญชีของคุณไม่สามารถเข้าถึงได้

ดำเนินเซสชันต่อ

POST /sessions/{session_id}/messages

ส่งข้อความไปยังเซสชันแบบต่อเนื่อง (persistent session) ที่มีอยู่แล้ว และรับการตอบกลับจากเอเจนต์ โดยค่าเริ่มต้นการตอบกลับจะสตรีมผ่าน SSE ตั้งค่า stream: false เพื่อรับผลลัพธ์เป็น JSON

เนื้อหาคำขอ

ฟิลด์ประเภทจำเป็นค่าเริ่มต้นคำอธิบาย
contentstringมีเงื่อนไข-ข้อความ จำเป็นต้องระบุ เว้นแต่มีการระบุ file_urls
file_urlsstring[]มีเงื่อนไข-URL ของไฟล์ที่จะแนบ จำเป็นต้องระบุ เว้นแต่มีการระบุ content
streambooleanไม่บังคับtruetrue สำหรับการสตรีมผ่าน SSE, false สำหรับ JSON การให้สิทธิ์ MCP จำเป็นต้องใช้การสตรีม
include_progressbooleanไม่บังคับtrueกำหนดเป็น false เพื่อละเว้นอีเวนต์ stream_progress ใช้กับการสตรีมเท่านั้น
modelstringไม่บังคับ-การกำหนดโมเดลเฉพาะครั้งสำหรับคำขอนี้เท่านั้น ใช้ ID โมเดลที่เสถียร เช่น claude-sonnet-5 การตั้งค่านี้ไม่เปลี่ยนโมเดลเริ่มต้นของเซสชัน
additional_contextobject[]ไม่-บริบทที่มีชื่อสำหรับคำขอนี้เท่านั้น ดู บริบทเพิ่มเติม

ตัวอย่าง - การสตรีม (ค่าเริ่มต้น)

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

ตัวอย่าง - JSON (ไม่สตรีม)

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

การตอบกลับ 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"
  }
}

หากเซสชันมีการรันที่กำลังทำงานอยู่หรือมีข้อความอยู่ในคิวแล้ว API จะส่งกลับ JSON 202 Accepted พร้อม status: "queued", session_id, run_id, และ message_id ข้อความของผู้ใช้จะถูกประมวลผลโดยการรันที่กำลังทำงานอยู่ คำขอที่มี additional_context จะได้รับ 409 busy แทน

การตอบกลับแบบไม่สตรีมเป็นไปตามกฎเดียวกันกับ ส่งข้อความ รวมถึงการตอบกลับ status: "cancelled" เมื่อการรันถูกยกเลิกก่อนที่เอเจนต์จะสร้างข้อความ

ข้อผิดพลาด

สถานะรหัสเงื่อนไข
400invalid_payloadJSON มีรูปแบบไม่ถูกต้อง หรือฟิลด์มีประเภทข้อมูลไม่ถูกต้อง
400bad_requestadditional_context ไม่ถูกต้อง
400content_or_uploaded_files_requiredไม่มีการระบุทั้ง content และ file_urls
400content_too_longเนื้อหาข้อความเกิน 32,000 token
400exceed_max_upload_filesมี URL ไฟล์ที่แตกต่างกันมากกว่า 10 รายการในคำขอเดียว
400unsupported_file_formatURL ไฟล์มีนามสกุลไฟล์ที่ไม่รองรับ
400invalid_file_urlURL ไฟล์มีรูปแบบไม่ถูกต้องหรือไม่ใช่ HTTPS
400invalid_model_selectionmodel ไม่ใช่ ID โมเดลที่ถูกต้อง หรือโมเดลของเซสชันไม่พร้อมใช้งานแล้ว
402insufficient_creditsมีเครดิตไม่เพียงพอสำหรับการส่งข้อความ
404session_not_foundไม่พบเซสชันที่ระบุ
404session_not_ownedเซสชันนี้เป็นของนักพัฒนารายอื่น หรือไม่ตรงกับ user ที่ระบุ
409busyเซสชันไม่สามารถใช้งานได้ชั่วคราวเนื่องจากมีการอัปเดตอื่นกำลังดำเนินการอยู่ หรือส่ง additional_context ขณะที่เซสชันมีการรันที่กำลังทำงานอยู่หรือมีข้อความอยู่ในคิว
429too_many_pendingเซสชันมีข้อความอยู่ในคิวครบ 200 รายการแล้ว
503service_unavailableบริการไม่พร้อมใช้งานชั่วคราว

Idempotency

POST /messages, POST /sessions/{session_id}/messages และ POST /invoke รองรับส่วนหัว Idempotency-Key แบบไม่บังคับ (สูงสุด 255 ตัวอักษร) ใช้คีย์ที่ไม่ซ้ำกันสำหรับการส่งของผู้ใช้ในแต่ละครั้งตามหลักตรรกะ เพื่อไม่ให้การลองใหม่ของเครือข่ายหรือการส่งซ้ำสองครั้งสร้างการรันที่ซ้ำกัน คีย์จะถูกเก็บไว้ 24 ชั่วโมง

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

ไม่ใช้การสตรีม: การลองใหม่จะส่งคืนการตอบกลับที่บันทึกไว้พร้อมส่วนหัว Idempotent-Replayed: true รวมถึงข้อผิดพลาดที่ส่งกลับหลังจากคำขอเริ่มประมวลผลแล้ว การตอบกลับ 202 Accepted ที่บันทึกไว้จะถูกส่งซ้ำโดยไม่มีการเปลี่ยนแปลง ให้ใช้ รับสถานะการรัน หรือ รายการข้อความ เพื่อตรวจสอบผลลัพธ์ คำขอที่ถูกปฏิเสธก่อนเริ่มประมวลผล เช่น ข้อผิดพลาดในการตรวจสอบความถูกต้องหรือข้อผิดพลาดด้านเครดิต จะไม่ถูกบันทึกไว้ ดังนั้นการลองใหม่จะถูกประเมินใหม่อีกครั้ง

การสตรีม: สตรีมจะไม่ถูกเล่นซ้ำ สำหรับ POST /messages และ POST /sessions/{session_id}/messages การลองใหม่ในระหว่างที่กำลังรันอยู่หรือหลังจากเสร็จสมบูรณ์แล้วจะส่งคืนข้อผิดพลาดเกี่ยวกับ idempotency พร้อม run_id เดิม และสำหรับคำขอแบบถาวรจะมี session_id ด้วย สำหรับคำขอแบบถาวร ให้ใช้ รับสถานะการรัน เพื่อตรวจสอบการรันที่กำลังทำงานอยู่ หรือ รายการข้อความ เพื่อดึงผลลัพธ์ที่ถูกบันทึกไว้แล้ว ผลลัพธ์ของ POST /invoke แบบสตรีมไม่สามารถดึงได้หลังจากสตรีมปิดลงแล้ว การลอง POST /invoke ใหม่จะส่งคืน id เดิมแทน run_id และ session_id

ตัวอย่างการลองใหม่ของการสตรีมที่เสร็จสมบูรณ์แล้ว:

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

ข้อผิดพลาดเกี่ยวกับ idempotency

สถานะรหัสเงื่อนไข
400bad_requestIdempotency-Key เกินความยาวสูงสุด
409idempotency_key_reusedมีการใช้คีย์เดียวกันกับคำขอที่แตกต่างกัน
409idempotency_key_in_useคำขอเดิมยังคงทำงานอยู่
409idempotency_key_reusedคำขอสตรีมเดิมเสร็จสมบูรณ์ไปแล้วและไม่สามารถเล่นซ้ำได้

รายการข้อความ

GET /sessions/{session_id}/messages

ส่งกลับรายการข้อความของเซสชันแบบแบ่งหน้า โดยค่าเริ่มต้นจะส่งกลับเฉพาะข้อความสนทนาประเภท external เท่านั้น หน้าแรกจะมีข้อความล่าสุด และในแต่ละหน้า ข้อความจะเรียงตามลำดับเวลา (จากเก่าไปใหม่) sequence เป็นเลขลำดับของข้อความภายในเซสชัน

พารามิเตอร์คิวรี

พารามิเตอร์ประเภทค่าเริ่มต้นสูงสุดคำอธิบาย
limitinteger20100จำนวนข้อความต่อหน้า
cursorstring--เคอร์เซอร์สำหรับการแบ่งหน้า
includestringexternal-ประเภทข้อความที่จะส่งกลับ: external, internal หรือ all

ตัวอย่าง

curl "https://api.jenova.ai/v1/sessions/ses_abc123/messages?limit=50" \
  -H "Authorization: Bearer jnv_sk_xxx"

การตอบกลับ 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
}

อ็อบเจ็กต์ข้อความ

ฟิลด์ประเภทคำอธิบาย
idstringID ของข้อความ (มีคำนำหน้า msg_)
session_idstringID ของเซสชันหลัก
sequenceintegerเลขลำดับภายในเซสชัน เลขลำดับอาจถูกนำกลับมาใช้ใหม่หลังจากมีการลบข้อความ
fromobjectอ็อบเจ็กต์ผู้ส่งซึ่งมี type (user หรือ agent) และ name
typestringexternal สำหรับข้อความสนทนา หรือ internal สำหรับขั้นตอนการทำงานของเอเจนต์
timestringtimestamp แบบ ISO 8601
contentstringเนื้อหาข้อความ มีอยู่ในข้อความประเภท external
modelstringID ของโมเดลที่ใช้สร้างการตอบกลับแบบคงที่ มีอยู่เฉพาะในข้อความของเอเจนต์เท่านั้น
filesarrayไฟล์ที่แนบมาหรือถูกสร้างขึ้นซึ่งรวมอยู่กับข้อความ ดู อ็อบเจ็กต์ไฟล์ ด้านล่าง ไม่มีฟิลด์นี้ในผลลัพธ์ของรายการข้อความและรับข้อความเมื่อข้อความไม่มีไฟล์
stop_reasonstringมีอยู่ในข้อความประเภท external ของเอเจนต์ที่มีเนื้อหา ค่าคือ end_run
agentstringslug ของเอเจนต์ที่ทำการรัน เมื่อมีข้อมูล
agent_namestringชื่อที่แสดงของเอเจนต์ที่ทำการรัน เมื่อมีข้อมูล
progress_eventsarrayกิจกรรมที่บันทึกไว้สำหรับข้อความประเภท internal เมื่อมีข้อมูล แต่ละรายการมีฟิลด์เดียวกับอีเวนต์ stream_progress

อ็อบเจ็กต์ไฟล์

ฟิลด์ประเภทคำอธิบาย
file_idstringID ไฟล์ของ Jenova เป็นค่าว่างเมื่อไม่ทราบ
namestringชื่อไฟล์
urlstringURL ของไฟล์ เป็นค่าว่างเมื่อไม่ทราบ
formatstringรูปแบบไฟล์เป็นตัวพิมพ์เล็ก เช่น pdf, png หรือ csv
sizeintegerขนาดไฟล์เป็นไบต์ เป็น 0 เมื่อไม่ทราบ

ข้อผิดพลาด

สถานะรหัสเงื่อนไข
400bad_requestพารามิเตอร์คิวรีไม่ถูกต้อง
404session_not_foundไม่มีเซสชันนี้อยู่
404session_not_ownedเซสชันนี้เป็นของนักพัฒนารายอื่น หรือไม่ตรงกับ user ที่ระบุมา

รับข้อความ

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

ดึงข้อมูลข้อความรายการเดียวตาม ID

พารามิเตอร์คิวรี

พารามิเตอร์ประเภทค่าเริ่มต้นคำอธิบาย
includestringexternalประเภทข้อความที่สามารถส่งกลับได้: external, internal หรือ all

การตอบกลับ 200 OK

ส่งกลับอ็อบเจ็กต์ข้อความรายการเดียวที่มีโครงสร้างเหมือนกับการตอบกลับแบบรายการ

ข้อผิดพลาด

สถานะรหัสเงื่อนไข
400bad_requestพารามิเตอร์คิวรีไม่ถูกต้อง
404session_not_foundไม่มีเซสชันนี้อยู่
404session_not_ownedเซสชันนี้เป็นของนักพัฒนารายอื่น หรือไม่ตรงกับ user ที่ระบุมา
404not_foundไม่มีข้อความนี้อยู่ในเซสชันนี้

ไฟล์แนบ

ส่ง URL แบบ HTTPS ที่เข้าถึงได้แบบสาธารณะในฟิลด์ file_urls

ขีดจำกัดค่า
จำนวนไฟล์สูงสุดต่อข้อความ10
ขนาดไฟล์สูงสุด20 MB ต่อไฟล์

รูปแบบที่รองรับ

  • รูปภาพ: JPG, JPEG, PNG, WebP
  • เอกสาร: PDF, DOCX, XLSX, PPTX, TXT, CSV, RTF, MD, HTML, XML, JSON, LOG
  • โค้ด: JS, TS, TSX, JSX, PY, Java, Go, C, CPP, H, HPP, CS, RB, PHP, RS, Swift, KT, Scala, SQL, CSS, YAML, YML

URL ของไฟล์จะถูกดึงข้อมูลเมื่อเอเจนต์อ่านไฟล์ระหว่างการรัน ไม่ใช่เมื่อคำขอได้รับการยอมรับ URL ที่ไม่สามารถดึงข้อมูลได้ หรือไฟล์ที่มีขนาดเกิน 20 MB จะไม่ถูกอ่าน แต่คำขอจะไม่ถูกปฏิเสธ

เมื่อแสดงรายการข้อความ ไฟล์ที่แนบมาจะปรากฏในอาร์เรย์ files ของข้อความ


บริบทเพิ่มเติม

ส่งบริบทที่มีชื่อสำหรับข้อความเดียวใน additional_context เช่น รายละเอียดบัญชีของผู้ใช้ปลายทาง บริบทนี้จะไม่ถูกบันทึกในประวัติข้อความ

ฟิลด์ประเภทจำเป็นคำอธิบาย
namestringจำเป็นตัวอักษรภาษาอังกฤษพิมพ์เล็ก ตัวเลข และขีดล่าง โดยขึ้นต้นด้วยตัวอักษร (สูงสุด 64 ตัวอักษร) ต้องไม่ซ้ำกันภายในคำขอ โดยไม่นับขีดล่างและรูปพหูพจน์
contentstringจำเป็นข้อความบริบท ต้องไม่เป็นค่าว่าง (สูงสุด 12,000 token)
ขีดจำกัดค่า
จำนวนรายการสูงสุดต่อข้อความ4
จำนวน token สูงสุดต่อรายการ12,000

ให้ใช้ชื่อที่สื่อความหมาย เช่น customer_profile หรือ order_details

รายการที่ไม่มี name หรือ content หรือมีค่าที่ไม่ใช่สตริง จะส่งกลับ 400 invalid_payload รายการที่ไม่ถูกต้องในลักษณะอื่นจะส่งกลับ 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 เซสชัน

เซสชันคือบทสนทนาที่คงอยู่ระหว่างผู้ใช้ปลายทางและเอเจนต์ การผสานรวมส่วนใหญ่สามารถสร้างเซสชันได้โดยปริยายผ่าน POST /messages

สร้างเซสชัน

POST /sessions

สร้างเซสชันที่ยังไม่มีข้อมูลใดๆ (empty persistent session) ซึ่งผูกกับเอเจนต์ที่ระบุ ใช้กรณีที่คุณต้องการรับ session ID ก่อนส่งข้อความแรก แต่โดยทั่วไปแล้วแนะนำให้ใช้ POST /messages แทน

หมายเหตุ: ephemeral ไม่สามารถใช้กับ POST /sessions ได้ หากต้องการส่งคำขอแบบครั้งเดียว ให้ใช้ POST /messages พร้อมกับ ephemeral: true

เนื้อหาคำขอ

ฟิลด์ประเภทจำเป็นคำอธิบาย
agentstringจำเป็นslug identifier ของเอเจนต์
userstringไม่บังคับตัวระบุผู้ใช้ปลายทางภายนอกของคุณ (สูงสุด 255 ตัวอักษร) หากไม่ระบุ จะใช้ค่าเริ่มต้นเป็นบัญชีนักพัฒนาของคุณ
session_namestringไม่บังคับชื่อที่แสดงของเซสชัน (สูงสุด 200 ตัวอักษร)

ตัวอย่าง

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

การตอบกลับ 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"
}

อ็อบเจ็กต์เซสชัน

ฟิลด์ประเภทคำอธิบาย
idstringID ของเซสชัน (มีคำนำหน้า ses_)
session_namestringชื่อที่แสดง
agentstringslug ของเอเจนต์
agent_detailsobjectรายละเอียดของเอเจนต์ซึ่งมี display_name มีอยู่เฉพาะเมื่อร้องขอด้วย include=agent
userstringตัวระบุผู้ใช้ปลายทาง เป็น null หากสร้างเซสชันโดยไม่ได้ระบุ user
modelstringโมเดลที่ใช้เมื่อข้อความไม่ได้ระบุโมเดล จะถูกกำหนดเป็นโมเดลเริ่มต้นของเอเจนต์เมื่อสร้างเซสชัน เป็นค่าว่างเมื่อเอเจนต์ให้ Jenova เลือกโมเดล
created_atstringtimestamp แบบ ISO 8601
updated_atstringtimestamp แบบ ISO 8601

ข้อผิดพลาด

สถานะรหัสเงื่อนไข
400invalid_payloadJSON มีรูปแบบไม่ถูกต้อง หรือฟิลด์มีประเภทข้อมูลไม่ถูกต้อง
400missing_required_fieldagent เป็นฟิลด์ที่จำเป็น
400bad_requestมีการระบุ ephemeral หรือ user/session_name มีความยาวเกินขีดจำกัดที่กำหนด
402insufficient_creditsเครดิตไม่เพียงพอสำหรับการสร้างเซสชัน
404agent_not_foundไม่พบเอเจนต์ หรือบัญชีของคุณไม่มีสิทธิ์เข้าถึงเอเจนต์นี้

รายการเซสชัน

GET /sessions

ส่งกลับรายการเซสชันของคุณแบบแบ่งหน้า โดยเรียงตามลำดับการอัปเดตล่าสุดก่อน

พารามิเตอร์คิวรี

พารามิเตอร์ประเภทค่าเริ่มต้นค่าสูงสุดคำอธิบาย
limitinteger20100จำนวนรายการต่อหน้า
cursorstring--cursor สำหรับการแบ่งหน้า
userstring--กรองตามตัวระบุผู้ใช้ปลายทาง (สูงสุด 255 ตัวอักษร)
agentstring--กรองตาม slug ของเอเจนต์
includestring--กำหนดเป็น agent เพื่อเพิ่ม agent_details ให้กับแต่ละเซสชัน

ตัวอย่าง

curl "https://api.jenova.ai/v1/sessions?user=user_12345&limit=10" \
  -H "Authorization: Bearer jnv_sk_xxx"

การตอบกลับ 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
}

ข้อผิดพลาด

สถานะรหัสเงื่อนไข
400bad_requestพารามิเตอร์คิวรีไม่ถูกต้อง

รับเซสชัน

GET /sessions/{session_id}

ดึงข้อมูลเซสชันเดียวตาม ID

พารามิเตอร์คิวรี

พารามิเตอร์ประเภทคำอธิบาย
includestringกำหนดเป็น agent เพื่อเพิ่ม agent_details ให้กับเซสชัน

การตอบกลับ 200 OK

ส่งกลับ อ็อบเจ็กต์เซสชัน

ข้อผิดพลาด

สถานะรหัสเงื่อนไข
400bad_requestพารามิเตอร์คิวรีไม่ถูกต้อง
404session_not_foundไม่พบเซสชัน
404session_not_ownedเซสชันนี้เป็นของนักพัฒนารายอื่น หรือไม่ตรงกับ user ที่ระบุ

เปลี่ยนชื่อเซสชัน

PATCH /sessions/{session_id}

อัปเดตชื่อที่แสดงของเซสชัน

เนื้อหาคำขอ

ฟิลด์ประเภทจำเป็นคำอธิบาย
session_namestringใช่ชื่อที่แสดงใหม่ (ไม่เกิน 200 ตัวอักษร)

การตอบกลับ 200 OK

ส่งกลับอ็อบเจ็กต์เซสชันที่อัปเดตแล้ว

ข้อผิดพลาด

สถานะรหัสเงื่อนไข
400invalid_payloadJSON มีรูปแบบไม่ถูกต้อง หรือฟิลด์มีประเภทไม่ถูกต้อง
400missing_required_fieldต้องระบุ session_name
400bad_requestsession_name มีความยาวเกินขีดจำกัดที่กำหนด
404session_not_foundไม่พบเซสชัน
404session_not_ownedเซสชันนี้เป็นของนักพัฒนารายอื่น หรือไม่ตรงกับ user ที่ระบุ
409busyเซสชันไม่สามารถใช้งานได้ชั่วคราวเนื่องจากมีการอัปเดตอื่นกำลังดำเนินการอยู่

ลบเซสชัน

DELETE /sessions/{session_id}

ลบเซสชันและข้อความทั้งหมดในเซสชันอย่างถาวร เซสชันต้องไม่มีการรันที่กำลังทำงานอยู่

การตอบกลับ 204 No Content

ข้อผิดพลาด

สถานะรหัสเงื่อนไข
404session_not_foundไม่พบเซสชัน
404session_not_ownedเซสชันนี้เป็นของนักพัฒนารายอื่น หรือไม่ตรงกับ user ที่ระบุ
409busyเซสชันมีการรันที่กำลังทำงานอยู่ - โปรดยกเลิกก่อน

การดำเนินการ

จุดเชื่อมต่อเหล่านี้เป็นตัวควบคุมสำหรับการกู้คืนและการแก้ไขเซสชันแบบต่อเนื่อง การผสานรวมส่วนใหญ่ต้องการเพียง ยกเลิกการรันที่กำลังทำงาน เท่านั้น ให้ใช้การดำเนินการอื่น ๆ เมื่อคุณตั้งใจที่จะเปลี่ยนแปลงหรือกู้คืนสถานะของเซสชัน การดำเนินการทั้งหมดสนับสนุนตัวป้องกันความเป็นเจ้าของ user แบบไม่บังคับที่อธิบายไว้ใน ผู้ใช้ปลายทาง

ยกเลิกการรันที่กำลังทำงาน

POST /sessions/{session_id}/cancel

ยกเลิกการรันของเอเจนต์ที่กำลังทำงานอยู่ การดำเนินการนี้จะไม่ลบข้อความที่เสร็จสมบูรณ์แล้วก่อนการยกเลิก

เนื้อหาคำขอ

ฟิลด์ประเภทจำเป็นคำอธิบาย
run_idstringไม่ตัวป้องกันการรันที่ล้าสมัยแบบไม่บังคับ หากระบุและไม่ตรงกับการรันที่กำลังทำงานอยู่ API จะส่งกลับ 409 stale_run

การตอบกลับ 204 No Content

ข้อผิดพลาด

สถานะรหัสเงื่อนไข
400invalid_payloadJSON มีรูปแบบไม่ถูกต้อง หรือฟิลด์มีประเภทข้อมูลไม่ถูกต้อง
400cancel_not_allowedไม่มีการรันที่กำลังทำงานให้ยกเลิก หรือไม่อนุญาตให้ยกเลิก
404session_not_foundไม่พบเซสชัน
404session_not_ownedเซสชันนี้เป็นของนักพัฒนารายอื่น หรือไม่ตรงกับ user ที่ระบุ
409stale_runrun_id ที่ระบุไม่ตรงกับการรันที่กำลังทำงานอยู่

เลิกทำการรันที่กำลังทำงาน

POST /sessions/{session_id}/undo

ยกเลิกการรันที่กำลังทำงาน รอให้หยุดทำงาน แล้วลบข้อความใด ๆ ที่ถูกเพิ่มเข้ามาแล้ว จะไม่มีการบันทึกผลลัพธ์เพิ่มเติมหลังจากมีการเลิกทำ

เนื้อหาคำขอ

ฟิลด์ประเภทจำเป็นคำอธิบาย
run_idstringไม่ตัวป้องกันการรันที่ล้าสมัยแบบไม่บังคับ หากระบุและไม่ตรงกับการรันที่กำลังทำงานอยู่ API จะส่งกลับ 409 stale_run

การตอบกลับ 200 OK

{
  "session_id": "ses_abc123",
  "run_id": "run_abc123",
  "deleted": ["msg_002", "msg_001"]
}

หากการรันถูกยกเลิกก่อนที่ข้อความใด ๆ จะเสร็จสมบูรณ์ deleted จะเป็นอาร์เรย์ว่าง

ข้อผิดพลาด

สถานะรหัสเงื่อนไข
400invalid_payloadJSON มีรูปแบบไม่ถูกต้อง หรือฟิลด์มีประเภทข้อมูลไม่ถูกต้อง
400cancel_not_allowedไม่มีการรันที่กำลังทำงานให้เลิกทำ หรือไม่อนุญาตให้ยกเลิก
404session_not_foundไม่พบเซสชัน
404session_not_ownedเซสชันนี้เป็นของนักพัฒนารายอื่น หรือไม่ตรงกับ user ที่ระบุ
409stale_runrun_id ที่ระบุไม่ตรงกับการรันที่กำลังทำงานอยู่
409busyเซสชันไม่สามารถใช้งานได้ชั่วคราวเนื่องจากมีการอัปเดตอื่นกำลังดำเนินการอยู่

ลบข้อความล่าสุด

POST /sessions/{session_id}/messages/delete

ลบข้อความล่าสุด count ข้อความออกจากเซสชันที่อยู่ในสถานะไม่ทำงาน รวมถึงข้อความ internal ด้วย ใช้ include=all ใน รายการข้อความ เพื่อดูข้อความเหล่านั้น เซสชันต้องไม่มีการรันที่กำลังทำงานอยู่

เนื้อหาคำขอ

ฟิลด์ประเภทจำเป็นคำอธิบาย
countintegerใช่จำนวนข้อความล่าสุดที่จะลบจากท้ายสุด (ต้องมากกว่า 0) ค่าที่มากกว่า 100 จะถือเป็น 100

การตอบกลับ 200 OK

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

ข้อผิดพลาด

สถานะรหัสเงื่อนไข
400invalid_payloadJSON มีรูปแบบไม่ถูกต้อง หรือฟิลด์มีประเภทข้อมูลไม่ถูกต้อง
400bad_requestไม่มี count, เป็นศูนย์, หรือเป็นค่าลบ; หรือไม่มีข้อความให้ลบ
404session_not_foundไม่พบเซสชัน
404session_not_ownedเซสชันเป็นของนักพัฒนารายอื่น หรือไม่ตรงกับ user ที่ระบุ
409busyเซสชันมีการรันที่กำลังทำงานอยู่

ฟอร์กเซสชัน

POST /sessions/{session_id}/fork

สร้างเซสชันใหม่โดยคัดลอกเซสชันต้นทางไปจนถึงข้อความที่ระบุ เซสชันต้นทางต้องไม่มีการรันที่กำลังทำงานอยู่

เนื้อหาคำขอ (ไม่บังคับ)

ฟิลด์ประเภทจำเป็นคำอธิบาย
message_idstringไม่ID ของข้อความที่เป็นจุดฟอร์ก หากไม่ระบุ จะฟอร์กจากข้อความล่าสุด

การตอบกลับ 201 Created

ส่งกลับอ็อบเจ็กต์เซสชันที่สร้างขึ้นใหม่ ซึ่งมีโครงสร้างเดียวกับการสร้างเซสชัน

ข้อผิดพลาด

สถานะรหัสเงื่อนไข
400invalid_payloadJSON มีรูปแบบไม่ถูกต้อง หรือฟิลด์มีประเภทข้อมูลไม่ถูกต้อง
400bad_requestmessage_id ไม่ถูกต้อง
402insufficient_creditsเครดิตไม่เพียงพอสำหรับการฟอร์กเซสชัน
404not_foundไม่พบ message_id ในเซสชันนี้
404session_not_foundไม่พบเซสชัน
404session_not_ownedเซสชันเป็นของนักพัฒนารายอื่น หรือไม่ตรงกับ user ที่ระบุ
409busyเซสชันต้นทางมีการรันที่กำลังทำงานอยู่

รับสถานะการรัน

GET /sessions/{session_id}/runs/{run_id}

ส่งกลับสถานะปัจจุบันของการรันที่กำลังทำงานอยู่ ใช้สิ่งนี้หลังจากการเชื่อมต่อ SSE หลุด หรือหลังได้รับการตอบกลับแบบ idempotency ที่ส่งกลับ run_id มา หลังจากการรันเสร็จสิ้น ให้ดึงผลลัพธ์ด้วย GET /sessions/{session_id}/messages

การตอบกลับ 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 จะเป็น running ขณะที่เอเจนต์กำลังทำงาน streaming เมื่อเริ่มสร้างข้อความตอบกลับแล้ว หรือ ended ในช่วงสั้นๆ หลังจากการรันเสร็จสิ้น การตอบกลับอาจรวม progress_events ที่มีกิจกรรมล่าสุดในรูปแบบเดียวกับ stream_progress ด้วย เมื่อ status เป็น ended หรือคำขอส่งกลับ 404 not_found ให้ดึงข้อความของเซสชัน

ข้อผิดพลาด

สถานะรหัสเงื่อนไข
404session_not_foundไม่พบเซสชัน
404session_not_ownedเซสชันเป็นของนักพัฒนารายอื่น หรือไม่ตรงกับ user ที่ระบุ
404not_foundการรันนี้ไม่ได้กำลังทำงานอยู่สำหรับเซสชันนี้

เครดิต

รับยอดคงเหลือ

GET /credits/balance

ส่งกลับยอดเครดิตคงเหลือปัจจุบันของคุณ

การตอบกลับ 200 OK

{
  "balance": "123.45"
}

API เอเจนต์

สร้างและแก้ไขเอเจนต์แบบกำหนดเองได้ในแดชบอร์ด การสนับสนุน API สำหรับการสร้างและแก้ไขเอเจนต์จะเปิดให้ใช้งานเร็ว ๆ นี้

เวิร์กโฟลว์แบบตั้งเวลา/เบื้องหลังยังไม่ได้รับการสนับสนุนผ่าน API ในขณะนี้ การสนับสนุนจะเปิดให้ใช้งานเร็ว ๆ นี้

รายการเอเจนต์

GET /agents

ส่งกลับรายการเอเจนต์ที่พร้อมใช้งานสำหรับบัญชีของคุณ ใช้ค่า agent เมื่อสร้างเซสชันหรือส่งข้อความ

การตอบกลับ 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"
    }
  ]
}
ฟิลด์ประเภทคำอธิบาย
agentstringslug ของเอเจนต์ที่คงที่ ใช้ส่งเป็นค่า agent
display_namestringชื่อที่แสดงในรูปแบบที่มนุษย์อ่านได้
descriptionstringคำอธิบายเอเจนต์

โมเดล

รายการโมเดล

GET /models

ส่งกลับโมเดลทั้งหมดที่สามารถใช้ในฟิลด์ model เมื่อส่งข้อความหรือเรียกใช้ POST /invoke

การตอบกลับ 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"
    }
  ]
}
ฟิลด์ประเภทคำอธิบาย
idstringตัวระบุโมเดลที่คงที่ ใช้ส่งเป็นค่า model ใน ส่งข้อความ หรือ เรียกใช้โมเดล
namestringชื่อที่แสดงในรูปแบบที่มนุษย์อ่านได้
thinking_variantstringID ของโมเดลรูปแบบ thinking/reasoning มีอยู่เฉพาะในโมเดลพื้นฐานที่รองรับการให้เหตุผลเท่านั้น

โมเดลที่มี thinking_variant รองรับการให้เหตุผลแบบขยาย (extended reasoning) ใช้ ID ของรูปแบบนี้โดยตรงในฟิลด์ model เพื่อเปิดใช้งาน

หากไม่ได้ระบุ model เมื่อส่งข้อความ ระบบจะใช้ model ของเซสชัน ซึ่งจะถูกกำหนดเป็นโมเดลเริ่มต้นของเอเจนต์เมื่อสร้างเซสชัน


เรียกใช้โมเดล

POST /invoke

ส่งพรอมต์ไปยังโมเดลโดยตรง โดยไม่ผ่านเอเจนต์ เซสชัน หรือเครื่องมือ โดยค่าเริ่มต้นการตอบกลับจะสตรีมผ่าน SSE ตั้งค่า stream: false เพื่อรับผลลัพธ์เป็น JSON

เนื้อหาคำขอ

ฟิลด์ประเภทจำเป็นค่าเริ่มต้นคำอธิบาย
modelstringใช่-ID โมเดลจาก รายการโมเดล
contentstringใช่-พรอมต์ รวมถึงคำสั่งต่างๆ
streambooleanไม่truetrue สำหรับการสตรีมแบบ SSE, false สำหรับ JSON
userstringไม่-ตัวระบุผู้ใช้ปลายทางภายนอกของคุณ (สูงสุด 255 ตัวอักษร) หากไม่ระบุ จะใช้ค่าเริ่มต้นเป็นบัญชีนักพัฒนาของคุณ

ตัวอย่าง

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

การตอบกลับ 200 OK

{
  "id": "inv_abc123",
  "model": "claude-sonnet-5",
  "content": "Sunlight filters through tall pines onto a quiet, mossy floor.",
  "usage": {
    "cost": "0.0004"
  }
}

การตอบกลับแบบสตรีมจะส่ง stream_started จากนั้นส่งอีเวนต์ stream_delta ขณะที่โมเดลสร้างข้อความ และจบด้วย stream_ended ซึ่งมี usage ให้เชื่อมค่า chunk_content ตามลำดับ seq เพื่อสร้างข้อความตอบกลับแบบสตรีม หากคำขอล้มเหลว จะส่ง stream_error ก่อน stream_ended อีเวนต์จะมี id แทน session_id และ run_id

usage.cost จะเป็น null เมื่อไม่มีข้อมูลค่าใช้จ่าย หากคำขอแบบไม่สตรีมล้มเหลวหลังจากเริ่มเรียกใช้โมเดลแล้ว การตอบกลับข้อผิดพลาดจะมีฟิลด์ id และ usage ระดับบนสุด

คำขอแบบสตรีมจำกัดไว้ที่ 120 นาที คำขอแบบไม่สตรีมจะรอผลลัพธ์นานสูงสุด 30 นาที แทนการส่งกลับ 202 Accepted และจะส่งกลับข้อผิดพลาดหากผลลัพธ์ยังไม่พร้อมภายในเวลานั้น

ข้อผิดพลาด

สถานะรหัสเงื่อนไข
400invalid_payloadJSON มีรูปแบบไม่ถูกต้อง หรือฟิลด์มีประเภทข้อมูลไม่ถูกต้อง
400missing_required_fieldต้องระบุ content
400content_too_longเนื้อหาเกิน 32,000 โทเค็น
400bad_requestuser เกินความยาวสูงสุด
400invalid_model_selectionไม่มี model หรือไม่ใช่ ID โมเดลที่ถูกต้อง
400content_policy_violationผู้ให้บริการโมเดลปฏิเสธคำขอเนื่องจากเหตุผลด้านนโยบายเนื้อหา
400llm_context_limit_reachedข้อมูลนำเข้าเกินหน้าต่างบริบทของโมเดล
402insufficient_creditsเครดิตไม่พอสำหรับการเรียกใช้โมเดล
500internal_errorข้อผิดพลาดของเซิร์ฟเวอร์ที่ไม่คาดคิด
502llm_api_errorข้อผิดพลาดจากผู้ให้บริการโมเดลหรือ API โมเดลต้นทาง
502llm_empty_responseโมเดลส่งคืนคำตอบว่าง
502llm_reasoning_limit_reachedโมเดลถึงขีดจำกัดการให้เหตุผลโดยยังไม่มีคำตอบ
502llm_generation_limit_reachedโมเดลถึงขีดจำกัดการสร้างโดยยังไม่มีคำตอบ
503service_unavailableบริการไม่พร้อมใช้งานชั่วคราว

เอกสาร

GET /docs?lang=en
GET /doc?lang=en

ส่งกลับเอกสารอ้างอิงนี้ในรูปแบบ Markdown ใช้ lang เพื่อเลือกภาษา


การสตรีม (SSE)

เมื่อไม่ได้ระบุ stream หรือระบุเป็น true (ค่าเริ่มต้น) การตอบกลับข้อความจะถูกส่งในรูปแบบ Server-Sent Events ใช้อีเวนต์ message_completed เพื่อระบุข้อความที่พร้อมสำหรับการดึงข้อมูลหรือแสดงผล

การหมดเวลา: การเชื่อมต่อ SSE จะเปิดอยู่จนกว่าการรันจะสิ้นสุด การรันแต่ละครั้งจำกัดไว้ที่ 120 นาที คำขอข้อความแบบไม่สตรีมจะรอนานสูงสุด 90 วินาที จากนั้นจะส่งกลับ 202 Accepted ในขณะที่การรันยังดำเนินต่อไป สำหรับ POST /invoke แบบไม่สตรีม ดู เรียกใช้โมเดล

ส่วนหัวการเชื่อมต่อ

สตรีมข้อความจะตั้งค่าส่วนหัวเหล่านี้:

Content-Type: text/event-stream
Cache-Control: no-cache
Connection: keep-alive
X-Accel-Buffering: no
X-Run-Id: run_abc123

X-Run-Id จะพร้อมใช้งานก่อนอีเวนต์ SSE แรก สตรีมของ POST /invoke จะไม่ตั้งค่า X-Run-Id ให้ใช้ id ใน stream_started แทน

การเชื่อมต่อใหม่และการกู้คืน

สตรีม SSE จะไม่ถูกเล่นซ้ำ หากการเชื่อมต่อขาดหายในคำขอแบบถาวร ให้ใช้ session_id และ run_id ที่บันทึกไว้เพื่อกู้คืนสถานะ:

curl "https://api.jenova.ai/v1/sessions/ses_abc123/runs/run_abc123" \
  -H "Authorization: Bearer jnv_sk_xxx"

หากการรันยังทำงานอยู่ คำขอนี้จะส่งกลับสถานะปัจจุบัน ข้อความส่วนที่เสร็จบางส่วน และความคืบหน้าล่าสุด หากได้รับผลลัพธ์เป็น status: "ended" หรือ 404 not_found แสดงว่าการรันนั้นไม่ได้ทำงานอยู่แล้ว ให้ดึงข้อความของเซสชันเพื่อตรวจสอบผลลัพธ์ที่เสร็จสมบูรณ์:

curl "https://api.jenova.ai/v1/sessions/ses_abc123/messages?limit=20" \
  -H "Authorization: Bearer jnv_sk_xxx"

รูปแบบเฟรม

เฟรม SSE แต่ละเฟรมเป็นไปตามรูปแบบมาตรฐาน:

event: <event_type>
data: <json_payload>

การขึ้นบรรทัดใหม่สองครั้งเป็นตัวสิ้นสุดของแต่ละเฟรม

ประเภทอีเวนต์

สตรีมประกอบด้วยเหตุการณ์วงจรชีวิต เดลตาข้อความ การคิด ความคืบหน้า คำเตือน การเสร็จสมบูรณ์ของข้อความ การเชื่อมต่อ MCP ข้อผิดพลาด เหตุการณ์สุดท้าย และ ping เหตุการณ์บางประเภทจะถูกส่งเมื่อเกี่ยวข้องเท่านั้น

สำหรับคำขอแบบชั่วคราว (ephemeral: true) อีเวนต์ SSE ทุกตัวจะไม่มี session_id ให้ใช้ run_id เท่านั้นในการเชื่อมโยงอีเวนต์ภายในสตรีมนั้นเพียงหนึ่งเดียว

สำหรับการตรวจสอบยืนยันครั้งสุดท้ายในคำขอแบบถาวร ให้รอ stream_ended แล้วจึงเรียก รายการข้อความ

ฟิลด์ทั่วไปในอีเวนต์ที่อยู่ในขอบเขตของการรัน:

ฟิลด์คำอธิบาย
session_idID ของเซสชัน ไม่มีในสตรีมแบบชั่วคราว ให้เก็บค่านี้จาก stream_started เพื่อใช้ในคำขอถัดไปเมื่อใช้ POST /messages แบบถาวร
run_idID ของการรันปัจจุบัน เมื่อมี
idID ของคำขอ invoke (มีคำนำหน้า inv_) มีอยู่เฉพาะในสตรีมของ POST /invoke ซึ่งไม่มี session_id หรือ run_id

stream_started

ส่งครั้งเดียวเมื่อการรันเริ่มต้น

ฟิลด์คำอธิบาย
agentslug ของเอเจนต์ในเซสชัน เมื่อมี

stream_delta

ส่งซ้ำ ๆ ขณะที่เอเจนต์สร้างข้อความตอบกลับที่มองเห็นได้ ให้เชื่อมค่า chunk_content ตามลำดับ seq เพื่อสร้างข้อความตอบกลับแบบสตรีม

event: stream_delta
data: {"session_id":"ses_abc123","run_id":"run_abc123","chunk_content":"To reset your ","seq":1}
ฟิลด์คำอธิบาย
chunk_contentส่วนย่อยของข้อความ
seqเลขลำดับส่วนย่อยที่เพิ่มขึ้นเรื่อย ๆ ภายในสตรีม

stream_thinking

ส่งซ้ำ ๆ ขณะที่เอเจนต์ปล่อยผลลัพธ์การคิดออกมา ใช้สำหรับตัวแสดงสถานะการคิดแยกต่างหากหรือมุมมองการตรวจสอบ (trace view) เท่านั้น อย่านำมาเชื่อมต่อเข้ากับข้อความตอบกลับสุดท้าย

ฟิลด์คำอธิบาย
contentส่วนย่อยของข้อความการคิด

stream_progress

รายงานกิจกรรมที่ผู้ใช้มองเห็นได้ระหว่างการสร้าง เช่น การอ่านเอกสาร การค้นหาเว็บ หรือการรอการดำเนินการจากผู้ใช้ เหตุการณ์เหล่านี้มีไว้สำหรับแสดงผลชั่วคราวใน UI โปรดละเว้นฟิลด์ที่ไม่รู้จัก ใช้ข้อความที่เสร็จสมบูรณ์แล้วเป็นประวัติข้อความที่เชื่อถือได้

กำหนด include_progress: false ในคำขอข้อความเพื่อละเว้นเฉพาะ stream_progress เท่านั้น อีเวนต์วงจรชีวิต ping message_completed ข้อผิดพลาด และอีเวนต์สุดท้ายยังคงถูกส่งเมื่อเกี่ยวข้อง

ฟิลด์คำอธิบาย
stateสถานะกิจกรรม: running, success, failed หรือ skipped ให้จัดการค่าที่ไม่รู้จักอย่างเหมาะสม
labelป้ายกิจกรรมที่มนุษย์อ่านเข้าใจได้

อีเวนต์ความคืบหน้าบางตัวอาจมี url, file_name, หรือ server_name เป็นคำแนะนำเพิ่มเติมสำหรับการแสดงผล

message_completed

ส่งทุกครั้งที่ข้อความเสร็จสมบูรณ์และพร้อมสำหรับการดึงข้อมูลหรือแสดงผล

นี่คือตัวบอกขอบเขต (boundary marker) ไม่ใช่อ็อบเจ็กต์ข้อความแบบสมบูรณ์ ให้ดึงข้อความหากคุณต้องการเนื้อหาหรือข้อมูลเมทาดาทา

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"}
ฟิลด์คำอธิบาย
message_idID ของข้อความที่เสร็จสมบูรณ์แล้ว
sequenceเลขลำดับภายในเซสชัน
fromอ็อบเจ็กต์ผู้ส่งซึ่งมี type (user หรือ agent) และ name
typeประเภทของข้อความ: external หรือ internal

mcp_connection

ส่งเมื่อเอเจนต์ต้องการให้ผู้ใช้ปลายทางเชื่อมต่อหรืออนุญาตเซิร์ฟเวอร์ MCP อย่างน้อยหนึ่งรายการก่อนที่จะดำเนินการต่อได้ เหตุการณ์นี้ใช้ได้เฉพาะในโหมดสตรีมมิงเท่านั้น

ฟิลด์คำอธิบาย
connection_server_listเซิร์ฟเวอร์ MCP ที่ต้องการการดำเนินการเชื่อมต่อ แต่ละเซิร์ฟเวอร์มี mcp_server_id, mcp_server_name และ auth_url ที่เป็นตัวเลือก
user_action_deadline_unixUnix timestamp เมื่อการดำเนินการเชื่อมต่อของผู้ใช้หมดอายุ

mcp_connection_resolved

ส่งเมื่อการดำเนินการเชื่อมต่อ MCP ของผู้ใช้ได้รับการแก้ไขหรือหมดอายุแล้ว

ไม่มีฟิลด์เพิ่มเติมนอกเหนือจากฟิลด์ทั่วไปที่อยู่ในขอบเขตของการรัน

warning

ส่งสำหรับคำเตือนที่ไม่ถึงขั้นร้ายแรงระหว่างการรัน

ฟิลด์คำอธิบาย
messageคำเตือนที่ไม่ถึงขั้นร้ายแรงที่มนุษย์อ่านเข้าใจได้
codeรหัสคำเตือน (ไม่บังคับ)

stream_error

ส่งเมื่อการรันล้มเหลว อาจมีอีเวนต์ stream_ended สุดท้ายตามมาพร้อมกับ success: false และ stop_reason: "error"

ฟิลด์คำอธิบาย
codeรหัสข้อผิดพลาด
messageข้อความแสดงข้อผิดพลาดที่มนุษย์อ่านเข้าใจได้

stream_ended

ส่งครั้งเดียวเมื่อการรันเสร็จสิ้น นี่คืออีเวนต์สุดท้ายของสตรีม

event: stream_ended
data: {"session_id":"ses_abc123","run_id":"run_abc123","success":true,"stop_reason":"end_run","usage":{"cost":"0.0032"}}

ตัวอย่างการรันที่ถูกยกเลิก:

event: stream_ended
data: {"session_id":"ses_abc123","run_id":"run_abc123","success":false,"stop_reason":"user_cancelled","usage":{"cost":"0.0012"}}
ฟิลด์คำอธิบาย
successบอกว่าการรันเสร็จสมบูรณ์หรือไม่
stop_reasonเหตุผลสิ้นสุดของการรัน: end_run, user_cancelled, user_action_timeout หรือ error
usageออบเจ็กต์การใช้งานสำหรับคำขอนี้ มี cost เสมอ และจะเป็น null เมื่อไม่มีข้อมูลค่าใช้จ่าย

ping

เฟรมสัญญาณคงชีพ (keepalive) ที่ส่งทุก 15 วินาที เพื่อป้องกันการหมดเวลาของพร็อกซี/CDN ให้ละเลยเฟรมเหล่านี้ในไคลเอนต์ของคุณ


การผสานรวมเซิร์ฟเวอร์ MCP

เชื่อมต่อเอเจนต์ของคุณกับเครื่องมือภายนอกผ่าน Model Context Protocol (MCP):

  • เซิร์ฟเวอร์ MCP ที่ Jenova จัดการ: เซิร์ฟเวอร์ที่ Jenova โฮสต์ไว้สำหรับการค้นหา การดึงเนื้อหา การสร้างเอกสาร และความสามารถอื่น ๆ ที่มีอยู่ในระบบ
  • เซิร์ฟเวอร์ MCP ระยะไกล: เซิร์ฟเวอร์ MCP ระยะไกลอื่น ๆ ที่กำหนดค่าไว้สำหรับเอเจนต์ของคุณ

เซิร์ฟเวอร์ MCP ต้องได้รับการกำหนดค่าในแดชบอร์ดเมื่อสร้างหรือแก้ไขเอเจนต์ของคุณ หากต้องการใช้เซิร์ฟเวอร์ MCP ของคุณเอง ให้เพิ่มเข้าไปในเอเจนต์แบบกำหนดเอง แล้วเรียกใช้เอเจนต์นั้นผ่าน API API จะดำเนินการเครื่องมือที่เปิดใช้งานไว้ในการกำหนดค่าของเอเจนต์ ไม่จำเป็นต้องตั้งค่าเพิ่มเติมในคำขอ API

เมื่อเอเจนต์ใช้เครื่องมือ MCP ระหว่างการตอบกลับ อีเวนต์ความคืบหน้าจะถูกส่งในสตรีมทันทีที่เกิดขึ้น:

event: stream_progress
data: {"session_id":"ses_...","run_id":"run_...","state":"running","label":"Searching Google"}

หากเอเจนต์ต้องการให้ผู้ใช้ปลายทางเชื่อมต่อหรืออนุญาตเซิร์ฟเวอร์ MCP ระหว่างการรัน การตอบกลับแบบสตรีมมิงอาจมีเหตุการณ์ mcp_connection และ mcp_connection_resolved แสดงรายการเซิร์ฟเวอร์ที่ต้องเชื่อมต่อให้ผู้ใช้ปลายทางเห็น และเปิด auth_url ที่ให้มาเมื่อมี ให้เปิดสตรีม SSE ค้างไว้ขณะที่ผู้ใช้ปลายทางเชื่อมต่อหรืออนุญาตเซิร์ฟเวอร์

หลังจากอนุมัติสิทธิ์แล้ว Jenova จะจัดเก็บ token หน้าต่างการอนุมัติสิทธิ์จะแสดงหน้าเสร็จสมบูรณ์ และการรันเดิมจะดำเนินการต่อโดยอัตโนมัติ ผู้ใช้ปลายทางไม่จำเป็นต้องส่งข้อความซ้ำ

หากผู้ใช้ปลายทางไม่เชื่อมต่อ ไม่อนุญาต หรือไม่ ข้ามหรือปิดเสียง ก่อน user_action_deadline_unix การรันจะสิ้นสุดด้วย stop_reason: "user_action_timeout" คุณยังสามารถยกเลิกการรันที่ใช้งานอยู่ด้วย POST /sessions/{session_id}/cancel

เก็บ auth_url ไว้ฝั่งไคลเอ็นต์ หากไคลเอ็นต์ตัดการเชื่อมต่อระหว่างการอนุญาต URL จะยังใช้ได้จนถึง user_action_deadline_unix สำหรับคำขอแบบถาวร ให้ตรวจสอบการรันด้วย รับสถานะการรัน หรือดึงข้อความหลังจากการรันเสร็จสิ้น

คำขอที่ไม่ใช่สตรีมมิง (stream: false) ไม่รองรับการดำเนินการของผู้ใช้สำหรับการเชื่อมต่อ MCP ใช้สตรีมมิงสำหรับเอเจนต์ที่อาจต้องมีการโต้ตอบนี้

ข้ามการเชื่อมต่อ MCP

POST /sessions/{session_id}/mcp/connection/skip

ยกเลิกการดำเนินการของผู้ใช้สำหรับการเชื่อมต่อ MCP ที่รอดำเนินการ และให้การรันดำเนินต่อโดยไม่มีการเชื่อมต่อนั้น

หากต้องการปิดเสียงพรอมป์การเชื่อมต่อในอนาคตสำหรับเซิร์ฟเวอร์หนึ่งรายการสำหรับผู้ใช้ปลายทางและเอเจนต์เดียวกัน ให้ระบุ mcp_server_id และ mute โดย mute รองรับระยะเวลา เช่น 30m, 24h หรือ 7d หรือค่า forever

เนื้อหาคำขอ

ฟิลด์ประเภทจำเป็นคำอธิบาย
run_idstringใช่ID การรันที่ใช้งานอยู่จากเหตุการณ์ mcp_connection
mcp_server_idstringไม่จำเป็นเมื่อใช้ mute; ใช้ mcp_server_id จากเหตุการณ์
mutestringไม่ระยะเวลา เช่น 30m, 24h หรือ 7d หรือค่า forever

การตอบกลับ 204 No Content

สตรีมจะส่ง mcp_connection_resolved จากนั้นการรันจะดำเนินต่อด้วย run_id เดิม

ข้อผิดพลาด

สถานะรหัสเงื่อนไข
400invalid_payloadJSON มีรูปแบบไม่ถูกต้อง หรือฟิลด์มีประเภทข้อมูลไม่ถูกต้อง
400bad_requestไม่มี run_id ไม่มีการรันที่ใช้งานอยู่ หรือไม่มีการเชื่อมต่อ MCP ให้ข้าม
400bad_requestmute ไม่ถูกต้อง ไม่มี mcp_server_id เมื่อกำหนด mute หรือ mcp_server_id ไม่ถูกต้องสำหรับเซสชันนี้
404session_not_foundไม่พบเซสชัน
404session_not_ownedเซสชันนี้เป็นของนักพัฒนารายอื่น หรือไม่ตรงกับ user ที่ระบุ
409stale_runrun_id ไม่ตรงกับการรันที่กำลังทำงานอยู่

การเรียกเก็บเงิน

ค่าใช้จ่ายทั้งหมดจะถูกหักออกจากยอดเครดิตสำหรับนักพัฒนาของคุณ ดูการใช้งานและเติมเครดิตได้ที่ www.jenova.ai/platform

ราคา

การดำเนินการค่าใช้จ่าย
สร้างเซสชัน$0.01 แบบตายตัวสำหรับเซสชันที่มีการเก็บข้อมูลถาวรทุกเซสชันที่สร้างโดย POST /sessions หรือ POST /messages
แยกสาขาเซสชัน (Fork Session)$0.05 แบบตายตัว โดยไม่มีค่าธรรมเนียมการสร้างเซสชันแยกต่างหาก
ส่งข้อความผันแปร (ดูรายละเอียดด้านล่าง)
เรียกใช้โมเดลผันแปร ตามโมเดลและจำนวนโทเค็น

ค่าใช้จ่ายของข้อความขึ้นอยู่กับ:

  • โมเดล - โมเดลแต่ละตัวมีค่าใช้จ่ายต่อ token แตกต่างกัน
  • ความยาวของบริบท - เซสชันที่ยาวขึ้นจะใช้ input token มากขึ้นต่อคำขอ
  • ความซับซ้อนของเวิร์กโฟลว์ - เวิร์กโฟลว์ที่ยาวขึ้นและการใช้เครื่องมือที่มากขึ้น (การค้นหาเว็บ การสร้างไฟล์ การวิเคราะห์เอกสาร) จะเพิ่มการใช้ token โดยรวม

ค่าใช้จ่ายจริงจะถูกส่งกลับเป็น stream_ended.usage.cost สำหรับคำขอแบบสตรีม และ usage.cost สำหรับคำขอ JSON แบบไม่สตรีม

การกันเครดิต

คำขอ POST /messages, POST /sessions/{session_id}/messages และ POST /invoke ทุกครั้งจะทำการ กันเครดิต $0.50 จากยอดเครดิตของคุณก่อนที่จะเริ่มดำเนินการ นี่คือการสำรองเงินทุนไว้สำหรับคำขอนั้น ข้อความที่ถูกเข้าคิวในการรันที่กำลังทำงานอยู่ (202 Accepted พร้อม status: "queued") จะไม่สร้างการกันเครดิตเพิ่มเติม; การใช้งานของการรันที่กำลังทำงานอยู่จะถูกตรวจสอบกับยอดเครดิตที่เหลือของคุณ

เมื่อคำขอเสร็จสมบูรณ์ การกันเครดิตจะถูกชำระตามค่าใช้จ่ายจริง และส่วนต่างจะถูกปลดปล่อยคืน หากค่าใช้จ่ายจริงเกินกว่าการกันเครดิต ส่วนต่างจะถูกเรียกเก็บเพิ่มด้วย ดังนั้นยอดเครดิตของคุณอาจติดลบได้ คำขอที่ถูกยกเลิกหรือล้มเหลวจะถูกเรียกเก็บเงินเฉพาะการใช้งานที่เกิดขึ้นจริงเท่านั้น หากคำขอล้มเหลวก่อนที่จะไปถึงโมเดล การกันเครดิตทั้งหมดจะถูกปลดปล่อยคืน

เนื่องจากการกันเครดิต ยอดเครดิตที่ใช้ได้ของคุณอาจดูต่ำลงชั่วคราวในช่วงที่คำขอกำลังดำเนินการอยู่ คุณต้องมียอดเครดิตที่ใช้ได้อย่างน้อย $0.50 สำหรับคำขอ POST /sessions/{session_id}/messages, POST /messages แบบชั่วคราว (ephemeral) หรือ POST /invoke คำขอ POST /messages แบบถาวรจะสร้างเซสชันด้วยและต้องมียอดเครดิตอย่างน้อย $0.51 เพื่อครอบคลุมการกันเครดิตบวกกับค่าธรรมเนียมการสร้างเซสชัน


การจำกัดอัตราการใช้งาน

บัญชีนักพัฒนาทุกบัญชีอยู่ภายใต้มิติการจำกัดอัตราการใช้งานสามมิติ:

มิติค่าเริ่มต้นคำอธิบาย
RPM (คำขอต่อนาที)200หน้าต่างเวลาตายตัว 60 วินาที
RPD (คำขอต่อวัน)10,000หน้าต่างเวลาตายตัว 24 ชั่วโมง
การทำงานพร้อมกัน (Concurrent)10จำนวนคำขอที่กำลังดำเนินการและการรันที่กำลังทำงานพร้อมกันสูงสุด

การรันจะใช้สล็อตพร้อมกันจนกว่าจะสิ้นสุด แม้หลังจากการตอบกลับ 202 Accepted หรือการตัดการเชื่อมต่อของไคลเอนต์ คำขอ POST /invoke จะใช้สล็อตจนกว่าจะเสร็จสิ้น แม้ว่าไคลเอนต์จะตัดการเชื่อมต่อ

คำขอ GET และ HEAD ไม่ใช้สล็อตพร้อมกัน cancel, undo และ mcp/connection/skip ก็ไม่ใช้สล็อตพร้อมกันเช่นกัน ดังนั้นการดำเนินการเหล่านี้ยังคงใช้ได้เมื่อสล็อตทั้งหมดถูกใช้งาน คำขอเหล่านี้ยังคงนับรวมใน RPM และ RPD

ขีดจำกัดต่อ IP แยกต่างหากที่ 1,200 คำขอต่อ 60 วินาทียังมีผลกับคำขอทั้งหมดด้วย และจะส่งกลับข้อผิดพลาด 429 rate_limit_exceeded เดียวกัน

ส่วนหัวการตอบกลับ

การตอบกลับ API ที่ผ่านการยืนยันตัวตนจะมีส่วนหัวการจำกัดอัตราการใช้งานรวมอยู่ด้วย:

ส่วนหัวคำอธิบาย
X-RateLimit-Limitขีดจำกัด RPM ของคุณ
X-RateLimit-Remainingจำนวนคำขอที่เหลือในหน้าต่างนาทีปัจจุบัน
X-RateLimit-ResetUnix timestamp ที่หน้าต่างปัจจุบันจะรีเซ็ต
Retry-Afterจำนวนวินาทีที่ต้องรอก่อนลองใหม่ ส่งมากับการตอบกลับ 429 rate_limit_exceeded และ 503 write_freeze_active

เมื่อเกินขีดจำกัดรายวัน X-RateLimit-Limit, X-RateLimit-Remaining และ X-RateLimit-Reset จะแสดงข้อมูลของหน้าต่างรายวันแทน

เมื่อเกินขีดจำกัด API จะส่งกลับ 429 Too Many Requests:

{
  "error": {
    "code": "rate_limit_exceeded",
    "message": "Rate limit exceeded. Please try again later."
  }
}

การจัดการข้อผิดพลาด

ข้อผิดพลาด HTTP ที่เกิดขึ้นทันทีและข้อผิดพลาดของการรันแบบไม่สตรีมจะใช้รูปแบบซองข้อมูลที่สอดคล้องกัน:

{
  "error": {
    "code": "error_code_string",
    "message": "Human-readable description"
  }
}

ข้อความแสดงข้อผิดพลาดจะถูกปรับให้เข้ากับท้องถิ่นตาม lang หรือ Accept-Language (ดู การปรับให้เข้ากับท้องถิ่น)

ข้อผิดพลาดของการรันแบบสตรีมจะถูกส่งในรูปแบบอีเวนต์ stream_error การรันที่ล้มเหลวอาจยังส่งอีเวนต์ stream_ended ครั้งสุดท้ายพร้อมกับ success: false และมีการกำหนด stop_reason ข้อผิดพลาดของการรันแบบไม่สตรีมจะมีออบเจกต์ usage ระดับบนสุด โดย cost จะเป็น null เมื่อไม่มีข้อมูลค่าใช้จ่าย

ข้อผิดพลาดต่อไปนี้อาจเกิดขึ้นได้กับทุกจุดเชื่อมต่อ:

สถานะรหัสเงื่อนไข
401invalid_api_keyคีย์ API ขาดหายไป ไม่ถูกต้อง หรือถูกเพิกถอนแล้ว
402developer_not_activatedบัญชีนักพัฒนาของคุณยังไม่ได้เปิดใช้งาน ซื้อเครดิตในแดชบอร์ดเพื่อเปิดใช้งาน
403developer_disabledบัญชีนักพัฒนาของคุณถูกปิดใช้งาน
403forbiddenคำขอจากเครือข่ายนี้ถูกบล็อก
413payload_too_largeเนื้อหาคำขอมีขนาดเกิน 1 MiB
429rate_limit_exceededเกินขีดจำกัดอัตราการใช้งาน ดู การจำกัดอัตราการใช้งาน
503write_freeze_activeคำขอเขียนข้อมูลถูกปิดใช้งานชั่วคราวเนื่องจากการบำรุงรักษา

ข้อผิดพลาดเฉพาะของแต่ละจุดเชื่อมต่อจะถูกอธิบายไว้ในเนื้อหาของแต่ละจุดเชื่อมต่อนั้น

ข้อผิดพลาดของการรันหลังจากเริ่มต้น

ข้อผิดพลาดของการรันจะปรากฏขึ้นหลังจากคำขอข้อความได้รับการยอมรับแล้ว ในโมดการสตรีม ข้อผิดพลาดเหล่านี้จะปรากฏเป็นอีเวนต์ stream_error และอาจตามด้วย stream_ended ที่มี success: false ในโมดไม่สตรีม ข้อผิดพลาดจะถูกส่งกลับเป็นการตอบกลับ JSON แสดงข้อผิดพลาดพร้อมกับรหัสสถานะ HTTP ตามด้านล่าง

รหัสสถานะ HTTP แบบไม่สตรีมรหัสเงื่อนไข
400content_policy_violationผู้ให้บริการโมเดลปฏิเสธคำขอเนื่องจากเหตุผลด้านนโยบายเนื้อหา
400llm_context_limit_reachedข้อมูลนำเข้าเกินหน้าต่างบริบทของโมเดล
404session_not_foundเซสชันถูกลบไปก่อนที่การรันจะสามารถดำเนินการได้
409busyเซสชันไม่ว่างหรือใช้งานไม่ได้ชั่วคราวก่อนที่การรันจะสามารถเริ่มต้นได้
413total_image_size_exceededขนาดรวมของรูปภาพเกินขีดจำกัดขนาดต่อคำขอของโมเดล
500internal_errorการรันล้มเหลวโดยไม่คาดคิด
500response_interruptedการรันถูกขัดจังหวะ ให้ส่งข้อความอีกครั้ง
500response_interrupted_message_savedการรันถูกขัดจังหวะหลังจากบันทึกข้อความของคุณแล้ว ให้ดึงข้อความของเซสชันก่อนส่งอีกครั้ง
502llm_api_errorข้อผิดพลาดจากผู้ให้บริการโมเดลหรือ API โมเดลต้นทาง
502llm_empty_responseโมเดลส่งคืนคำตอบว่าง
502llm_reasoning_limit_reachedโมเดลถึงขีดจำกัดการให้เหตุผลโดยยังไม่มีคำตอบ
502llm_generation_limit_reachedโมเดลถึงขีดจำกัดการสร้างโดยยังไม่มีคำตอบ

การแบ่งหน้า

รายการเซสชันและรายการข้อความใช้ การแบ่งหน้าแบบ cursor:

{
  "items": [],
  "next_cursor": "2026-05-19T11:15:00Z|ses_abc123",
  "has_more": true
}
พารามิเตอร์ประเภทค่าเริ่มต้นค่าสูงสุดคำอธิบาย
limitinteger20100จำนวนรายการต่อหน้า
cursorstring--cursor ที่ได้จาก next_cursor ในคำขอก่อนหน้า

ส่ง next_cursor เป็นพารามิเตอร์คิวรี cursor เพื่อดึงหน้าถัดไป โดยเข้ารหัสค่าสำหรับ URL (URL-encode) เมื่อ has_more เป็น false แสดงว่าไม่มีผลลัพธ์เพิ่มเติมแล้ว หาก limit อยู่นอกช่วง 1-100 หรือ cursor ไม่ถูกต้อง จะส่งกลับ 400 bad_request


การปรับให้เข้ากับท้องถิ่น

จุดเชื่อมต่อทั้งหมดรองรับพารามิเตอร์คิวรี lang แบบไม่บังคับ เพื่อควบคุมภาษาของข้อความแสดงข้อผิดพลาดและเนื้อหาที่ปรับให้เข้ากับท้องถิ่นอื่น ๆ

แหล่งที่มาลำดับความสำคัญตัวอย่าง
พารามิเตอร์คิวรี langสูงสุด?lang=zh
ส่วนหัว Accept-LanguageสำรองAccept-Language: ja
ค่าเริ่มต้นต่ำสุดEnglish (en)

คุณสามารถเพิ่ม ?lang=xx ต่อท้าย URL ของคำขอใดก็ได้:

POST /sessions?lang=zh
GET /sessions/ses_abc123/messages?lang=ja

ภาษาที่รองรับ: en, zh, ja, ko, es, fr, de, it, pt, ru, id, th, vi


ความเป็นส่วนตัวและข้อมูล

Jenova ไม่ใช้พรอมต์ API, ผลลัพธ์, ประวัติการสนทนา, ไฟล์ที่อัปโหลด, คำสั่งของเอเจนต์ หรือฐานความรู้ ในการฝึกโมเดลของ Jenova

สำหรับผู้ให้บริการโมเดลบุคคลที่สาม Jenova ใช้ช่องทาง API เชิงพาณิชย์ การตั้งค่าบัญชี ข้อผูกพันตามสัญญา หรือการเลือกไม่เข้าร่วม เพื่อป้องกันไม่ให้เนื้อหาของลูกค้าถูกนำไปใช้ในการฝึกโมเดลของผู้ให้บริการ

Jenova จัดเก็บและประมวลผลข้อมูล API โดยใช้โครงสร้างพื้นฐานในสหรัฐอเมริกา ผู้ให้บริการบุคคลที่สามอาจประมวลผลข้อมูลในเขตอำนาจศาลอื่น ๆ ตามที่ระบุไว้ในนโยบายความเป็นส่วนตัวและข้อกำหนดการใช้งาน

สำหรับรายละเอียดทั้งหมด ดู ข้อกำหนดการใช้งาน, นโยบายความเป็นส่วนตัว และ นโยบายการใช้งาน


การสนับสนุน