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

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

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

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


สารบัญ


ภาพรวม

สร้างและรันเอเจนต์ AI ระดับพร้อมใช้งานจริงได้โดยไม่ต้องประกอบสแต็กเบื้องหลังด้วยตัวเอง Jenova Agent API รวมทุกความสามารถหลักไว้ในบริการที่มีการจัดการแบบครบวงจรเดียว:

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

  • การประสานงานเอเจนต์ (Agent Orchestration): เลเยอร์การประสานงานแบบรวมศูนย์ที่ประสานโมเดล เครื่องมือ หน่วยความจำ และการค้นคืนข้อมูลตลอดเวิร์กโฟลว์ที่ซับซ้อน
  • หน่วยความจำและบริบท: หน่วยความจำและบริบทของการสนทนาแบบไม่จำกัดถูกฝังอยู่ในทุกเซสชัน ไม่จำเป็นต้องมีการจัดการสถานะภายนอก
  • เครื่องมือและ MCP: การผสานรวมเครื่องมือแบบไม่จำกัดกับเครื่องมือดั้งเดิมของแพลตฟอร์มและเซิร์ฟเวอร์ MCP ระยะไกลใด ๆ พร้อมใช้งานทันที
  • ใช้โมเดลใดก็ได้: ขับเคลื่อนเอเจนต์ของคุณด้วยโมเดลจาก OpenAI, Anthropic, Google, xAI, Qwen และอื่น ๆ ผ่านการผสานรวมเพียงจุดเดียว
  • พื้นที่จัดเก็บที่มีการจัดการครบวงจร: ฐานข้อมูลเชิงสัมพันธ์และฐานข้อมูลเวกเตอร์ที่มีการจัดการพร้อม RAG ในตัว ไม่ต้องจัดหาหรือปรับขนาดโครงสร้างพื้นฐานเอง
  • ระดับพร้อมใช้งานจริง: ใช้งานโดยผู้ใช้หลายแสนคน โครงสร้างพื้นฐานที่มีการจัดการครบวงจร API ที่มีความเสถียร ออกแบบมาเพื่อรองรับทราฟฟิกระดับการใช้งานจริง

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

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 และเว็บแอป

ข้อความ

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

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

การรัน

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

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

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

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

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


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

ยืนยันตัวตนทุกคำขอด้วย 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 ต้องใช้การสตรีม
modelstringไม่-การกำหนดโมเดลแทนที่แบบครั้งเดียวสำหรับคำขอนี้เท่านั้น ใช้ ID โมเดลที่มั่นคง เช่น claude-sonnet-5 ไม่เปลี่ยนแปลงโมเดลเริ่มต้นของเซสชัน

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

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) การตอบกลับแบบไม่สตรีมจะส่งกลับรูปแบบ JSON ของข้อความตามที่แสดงไว้ใน ดำเนินเซสชันต่อ รวมถึง stop_reason และ usage สำหรับคำขอที่เสร็จสมบูรณ์

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

ข้อผิดพลาด

สถานะรหัสเงื่อนไข
400missing_required_fieldต้องระบุ agent
400invalid_payloadJSON มีรูปแบบไม่ถูกต้อง หรือฟิลด์มีประเภทข้อมูลไม่ถูกต้อง
400bad_requestโหมด ephemeral ไม่ถูกต้อง หรือ user/session_name เกินความยาวสูงสุด
400content_or_uploaded_files_requiredไม่มีการระบุทั้ง content และ file_urls
400content_too_longเนื้อหาข้อความเกินความยาว token สูงสุด
400exceed_max_upload_filesมี URL ไฟล์มากกว่า 10 รายการในคำขอเดียว
400unsupported_file_formatURL ไฟล์มีนามสกุลไฟล์ที่ไม่รองรับ
400invalid_file_urlURL ไฟล์มีรูปแบบไม่ถูกต้อง หรือไม่ใช่ HTTPS
400invalid_model_selectionโมเดลที่กำหนดแทนที่ไม่ใช่โมเดลที่ใช้งานจริงที่ถูกต้อง
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 จำเป็นต้องใช้การสตรีม
modelstringไม่บังคับ-การกำหนดโมเดลเฉพาะครั้งสำหรับคำขอนี้เท่านั้น ใช้ ID โมเดลที่เสถียร เช่น claude-sonnet-5 การตั้งค่านี้ไม่เปลี่ยนโมเดลเริ่มต้นของเซสชัน

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

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 ข้อความของผู้ใช้จะถูกประมวลผลโดยการรันที่กำลังทำงานอยู่

ข้อผิดพลาด

สถานะรหัสเงื่อนไข
400invalid_payloadJSON มีรูปแบบไม่ถูกต้อง หรือฟิลด์มีประเภทข้อมูลไม่ถูกต้อง
400content_or_uploaded_files_requiredไม่มีการระบุทั้ง content และ file_urls
400content_too_longเนื้อหาข้อความเกินความยาว token สูงสุดที่กำหนด
400exceed_max_upload_filesมี URL ไฟล์มากกว่า 10 รายการในคำขอเดียว
400unsupported_file_formatURL ไฟล์มีนามสกุลไฟล์ที่ไม่รองรับ
400invalid_file_urlURL ไฟล์มีรูปแบบไม่ถูกต้องหรือไม่ใช่ HTTPS
400invalid_model_selectionการกำหนดโมเดลไม่ใช่โมเดลที่ใช้งานจริง (production model) ที่ถูกต้อง
402insufficient_creditsมีเครดิตไม่เพียงพอสำหรับการส่งข้อความ
404session_not_foundไม่พบเซสชันที่ระบุ
404session_not_ownedเซสชันนี้เป็นของนักพัฒนารายอื่น หรือไม่ตรงกับ user ที่ระบุ

Idempotency

POST /messages และ POST /sessions/{session_id}/messages รองรับส่วนหัว Idempotency-Key แบบไม่บังคับ ใช้คีย์ที่ไม่ซ้ำกันสำหรับการส่งของผู้ใช้ในแต่ละครั้งตามหลักตรรกะ เพื่อไม่ให้การลองใหม่ของเครือข่ายหรือการส่งซ้ำสองครั้งสร้างการรันที่ซ้ำกัน

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

ไม่ใช้การสตรีม: การลองใหม่จะส่งคืนการตอบกลับ 200 หรือ 202 ที่บันทึกไว้พร้อมส่วนหัว Idempotent-Replayed: true

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

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

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

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

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

GET /sessions/{session_id}/messages

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

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

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

ตัวอย่าง

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

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

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

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

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

ข้อผิดพลาด

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

รับข้อความ

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

ดึงข้อมูลข้อความที่มองเห็นได้รายการเดียวตาม ID

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

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

ข้อผิดพลาด

สถานะรหัสเงื่อนไข
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

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


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

ข้อผิดพลาด

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

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

GET /sessions

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

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

พารามิเตอร์ประเภทคำอธิบาย
limitintegerจำนวนรายการต่อหน้า (ค่าเริ่มต้น 20 สูงสุด 100)
cursorstringcursor สำหรับการแบ่งหน้า
userstringกรองตามตัวระบุผู้ใช้ปลายทาง (สูงสุด 255 ตัวอักษร)
agentstringกรองตาม slug ของเอเจนต์

ตัวอย่าง

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

ข้อผิดพลาด

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

รับเซสชัน

GET /sessions/{session_id}

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

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

ส่งกลับออบเจ็กต์เซสชันในรูปแบบเดียวกันกับการตอบกลับของการสร้างเซสชัน

ข้อผิดพลาด

สถานะรหัสเงื่อนไข
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 ที่ระบุ

ลบเซสชัน

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

ข้อผิดพลาด

สถานะรหัสเงื่อนไข
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 จะเป็นอาร์เรย์ว่าง

ข้อผิดพลาด

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

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

POST /sessions/{session_id}/messages/delete

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

เนื้อหาคำขอ

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

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

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

ข้อผิดพลาด

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

ฟอร์กเซสชัน

POST /sessions/{session_id}/fork

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

เนื้อหาคำขอ

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

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

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

ข้อผิดพลาด

สถานะรหัสเงื่อนไข
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"
}

การตอบกลับอาจรวมคำแนะนำความคืบหน้าล่าสุดในขณะที่การรันยังทำงานอยู่ด้วย

ข้อผิดพลาด

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

เครดิต

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

GET /credits/balance

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

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

{
  "balance": "123.45"
}

API เอเจนต์

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

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

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

GET /agents

ส่งกลับรายการเอเจนต์ที่พร้อมใช้งานสำหรับคีย์ API ของคุณ ใช้ค่า 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 เมื่อส่งข้อความ

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

{
  "models": [
    {
      "id": "claude-opus-4-8",
      "name": "Claude Opus 4.8",
      "thinking_variant": "claude-opus-4-8-thinking"
    },
    {
      "id": "claude-opus-4-8-thinking",
      "name": "Claude Opus 4.8 (Thinking)"
    },
    {
      "id": "kimi-k2.6",
      "name": "Kimi K2.6",
      "thinking_variant": "kimi-k2.6-thinking"
    }
  ]
}
ฟิลด์ประเภทคำอธิบาย
idstringตัวระบุโมเดลที่คงที่ ใช้ส่งเป็นค่า model ใน Send Message
namestringชื่อที่แสดงในรูปแบบที่มนุษย์อ่านได้
thinking_variantstringID ของโมเดลรูปแบบ thinking/reasoning มีอยู่เฉพาะในโมเดลพื้นฐานที่รองรับการให้เหตุผลเท่านั้น

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

หากไม่ได้ระบุ model เมื่อส่งข้อความ ระบบจะใช้โมเดลเริ่มต้นของเอเจนต์


เอกสาร

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

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


การสตรีม (SSE)

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

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

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

การตอบกลับ SSE จะตั้งค่าส่วนหัวเหล่านี้:

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 แรก

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

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

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

หากการรันยังทำงานอยู่ คำขอนี้จะส่งกลับสถานะปัจจุบัน ข้อความส่วนที่เสร็จบางส่วน และความคืบหน้าล่าสุด หากได้รับผลลัพธ์เป็น 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 แล้วจึงเรียก List Messages

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

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

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, in-progress, success, failed, skipped, complete, cancelled และอื่น ๆ ให้จัดการค่าที่ไม่รู้จักอย่างเหมาะสม
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":"Jenova"},"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 เมื่อสามารถคำนวณได้

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 สำหรับคำขอแบบถาวร ให้เชื่อมต่อใหม่ด้วย Get Run Status หรือดึงข้อความหลังจากการรันเสร็จสิ้น

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

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

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

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

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

เนื้อหาคำขอ

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

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

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

ข้อผิดพลาด

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

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

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

ราคา

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

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

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

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

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

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

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

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


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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

การแบ่งหน้า

จุดเชื่อมต่อประเภทรายการใช้ การแบ่งหน้าแบบ cursor:

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

ส่ง next_cursor เป็นพารามิเตอร์คิวรี cursor เพื่อดึงหน้าถัดไป เมื่อ has_more เป็น false แสดงว่าไม่มีผลลัพธ์เพิ่มเติมแล้ว


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

จุดเชื่อมต่อทั้งหมดรองรับพารามิเตอร์คิวรี 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 โดยใช้โครงสร้างพื้นฐานในสหรัฐอเมริกา ผู้ให้บริการบุคคลที่สามอาจประมวลผลข้อมูลในเขตอำนาจศาลอื่น ๆ ตามที่ระบุไว้ในนโยบายความเป็นส่วนตัวและข้อกำหนดการใช้งาน

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


การสนับสนุน