Tài liệu tham khảo Jenova Agent API
URL cơ sở: https://api.jenova.ai/v1
Xác thực: Bearer token trong tiêu đề Authorization
Mục lục
- Tổng quan
- Bắt đầu nhanh
- Khái niệm cốt lõi
- Xác thực
- Điểm cuối API
- Truyền phát trực tuyến (SSE)
- Tích hợp Máy chủ MCP
- Thanh toán
- Giới hạn tốc độ
- Xử lý lỗi
- Phân trang
- Bản địa hóa
- Quyền riêng tư và Dữ liệu
- Hỗ trợ
Tổng quan
Vận hành các tác nhân tùy chỉnh ngay trong sản phẩm hoặc workflow của bạn chỉ sau vài phút. Thiết lập tác nhân của bạn cho bất kỳ tác vụ nào, chọn bất kỳ mô hình và công cụ nào, và để Jenova đảm nhận agent harness, cơ sở dữ liệu và mở rộng quy mô.
Bộ công nghệ Tác nhân đầy đủ:
- Agent Harness được quản lý: Một lệnh gọi vào, công việc hoàn chỉnh trả về. Tác nhân của bạn nghiên cứu, suy luận, gọi công cụ và tạo ra các tệp — đúng như bạn hướng dẫn.
- Ngữ cảnh và Bộ nhớ không giới hạn: Quản lý ngữ cảnh dựa trên RAG và cơ chế độc quyền theo dõi trạng thái phiên cho phép bộ nhớ không giới hạn trong suốt một cuộc hội thoại.
- Thư viện công cụ và MCP: Kết nối với thư viện của chúng tôi gồm 30+ công cụ và server MCP, như tìm kiếm, tạo hình ảnh, email và hơn thế nữa — hoặc tích hợp server MCP của riêng bạn.
- Chuyển đổi mượt mà sang bất kỳ mô hình nào: Triển khai các mô hình từ OpenAI, Anthropic, Google, xAI hoặc các nhà cung cấp mã nguồn mở hàng đầu, và chuyển đổi giữa các mô hình này chỉ với một tham số.
- Tri thức và RAG được quản lý: Jenova đảm nhận pipeline RAG từ đầu đến cuối — chunking, lập chỉ mục, lưu trữ và truy xuất.
- Đã kiểm chứng ở quy mô lớn: Triển khai trên hạ tầng dày dạn thực chiến, đang vận hành hàng trăm tác nhân thực tế trong production. Không phải khởi tạo, mở rộng hay bảo trì bất kỳ cluster nào.
Bắt đầu nhanh
1. Lấy Khóa API của bạn
Tạo một khóa API từ bảng điều khiển dành cho nhà phát triển tại www.jenova.ai/platform. Các khóa sử dụng định dạng jnv_sk_* và được truyền dưới dạng Bearer token.
2. Chọn hoặc Tạo một Tác nhân
Chọn một tác nhân dựng sẵn từ nền tảng, hoặc tạo một tác nhân tùy chỉnh trong bảng điều khiển với các chỉ dẫn, cấu hình mô hình, tệp cơ sở kiến thức, công cụ và máy chủ MCP.
3. Gửi Tin nhắn đầu tiên của bạn
Tạo một phiên và gửi một tin nhắn trong một lần gọi:
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?"
}'
Phản hồi được truyền trở lại dưới dạng 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"}}
Ghi lại session_id từ stream_started để dùng cho các yêu cầu tiếp theo. Đối với các phản hồi JSON đồng bộ, xem Gửi Tin nhắn.
Khái niệm cốt lõi
Tác nhân
Một tác nhân AI mà bạn tương tác qua API. Mỗi tác nhân có một slug duy nhất (ví dụ: my-support-agent) được dùng làm giá trị agent trong các lệnh gọi API.
- Dựng sẵn: Chọn từ các tác nhân hiện có trên nền tảng.
- Tùy chỉnh: Cấu hình tác nhân riêng của bạn trong bảng điều khiển với các chỉ dẫn, mô hình, cơ sở kiến thức, công cụ và máy chủ MCP.
Phiên
Một luồng hội thoại độc lập giữa một người dùng cuối và một tác nhân.
- Định danh: ID có tiền tố (ví dụ:
ses_abc123). - Phạm vi: Có thể tồn tại nhiều phiên cho cùng một tác nhân và người dùng cuối, mỗi phiên có trạng thái hội thoại độc lập.
- Vòng đời: Các phiên tồn tại vô thời hạn cho đến khi bị xóa qua API. Đối với các nhiệm vụ một lần không cần phiên, hãy sử dụng
POST /messagesvớiephemeral: true. - Cách ly nền tảng: Các phiên API tách biệt hoàn toàn với các hội thoại trong ứng dụng web Jenova. Người dùng cuối, lịch sử phiên và thanh toán là độc lập giữa API và ứng dụng web.
Tin nhắn
Một mục đơn lẻ trong lịch sử hội thoại của một phiên, được trả về bởi các điểm cuối Tin nhắn. Mỗi tin nhắn bao gồm một đối tượng from có cấu trúc với type (user hoặc agent) và name, cùng với type của tin nhắn:
external- một tin nhắn hội thoại được dự định hiển thị dưới dạng nội dung chat.internal- một tin nhắn tùy chọn đại diện cho các bước làm việc của tác nhân trong một lượt chạy, chẳng hạn như lệnh gọi công cụ hoặc truy xuất.
Lượt chạy
Một lần thực thi tác nhân đơn lẻ được tạo ra khi bạn gửi một tin nhắn. Một lượt chạy có một run_id, có thể truyền phát các sự kiện trong khi đang hoạt động, và có thể tạo ra một hoặc nhiều tin nhắn hoàn chỉnh. Mỗi phiên chỉ có thể có một lượt chạy đang hoạt động tại một thời điểm.
Người dùng cuối
Trường user giới hạn phạm vi các phiên cho một người dùng cuối trong ứng dụng của bạn. Hãy sử dụng một ID ổn định và không mang thông tin định danh, chẳng hạn như ID người dùng nội bộ hoặc UUID của bạn. Tránh sử dụng email hoặc các thông tin cá nhân khác trừ khi ứng dụng của bạn yêu cầu. Các phiên được tạo với cùng giá trị user được nhóm lại với nhau, cho phép liệt kê phiên theo từng người dùng.
Nếu user bị bỏ qua, phiên sẽ được giới hạn phạm vi theo tài khoản nhà phát triển của bạn và không thể lọc theo người dùng cuối sau này. Hãy truyền user trong môi trường sản xuất.
Đối với các yêu cầu trên phiên đã tồn tại (bất kỳ điểm cuối nào có {session_id} trong đường dẫn), user là một cơ chế bảo vệ quyền sở hữu tùy chọn. Nếu bạn cung cấp trường này, nó phải khớp với giá trị user đã dùng khi phiên được tạo; nếu không, API sẽ trả về 404 session_not_owned. Hãy gửi trường này như một tham số truy vấn trong các yêu cầu GET và DELETE, và trong phần nội dung JSON của các yêu cầu POST và PATCH. Tham số truy vấn user trên yêu cầu POST hoặc PATCH sẽ trả về 400 bad_request.
Xác thực
Xác thực mọi yêu cầu bằng Bearer token trong tiêu đề Authorization:
Authorization: Bearer jnv_sk_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Khóa API được tạo từ bảng điều khiển dành cho nhà phát triển.
User-Agent là tùy chọn. Các SDK có thể thiết lập giá trị này để phục vụ chẩn đoán, nhưng API không yêu cầu điều đó.
Định dạng khóa: Khóa bắt đầu bằng tiền tố jnv_sk_ theo sau là một chuỗi ngẫu nhiên được mã hóa base62.
Giới hạn: Mỗi tài khoản nhà phát triển có thể có tối đa 10 khóa API đang hoạt động.
Điểm cuối API
API Tin nhắn
Gửi Tin nhắn là đường dẫn API chính. Sử dụng POST /messages cho tin nhắn đầu tiên; nó sẽ tạo phiên và bắt đầu lượt chạy trong một yêu cầu duy nhất. Sử dụng POST /sessions/{session_id}/messages khi tiếp tục một session_id đã được ghi lại.
Gửi Tin nhắn
POST /messages
Tạo một phiên lâu dài và gửi tin nhắn đầu tiên trong một yêu cầu duy nhất. Đặt ephemeral: true để tạo yêu cầu truyền phát trực tuyến một lần không trả về ID phiên và không thể tiếp tục. Dữ liệu của yêu cầu sẽ bị xóa ngay sau khi yêu cầu hoàn tất.
Nội dung yêu cầu
| Trường | Loại | Bắt buộc | Mặc định | Mô tả |
|---|---|---|---|---|
agent | string | Có | - | Định danh slug của tác nhân |
content | string | Có điều kiện | - | Nội dung văn bản tin nhắn. Bắt buộc trừ khi đã cung cấp file_urls |
file_urls | string[] | Có điều kiện | - | URL của các tệp cần đính kèm. Bắt buộc trừ khi đã cung cấp content |
user | string | Không | - | Định danh người dùng cuối bên ngoài của bạn (tối đa 255 ký tự). Nếu bỏ trống, giá trị mặc định sẽ là tài khoản nhà phát triển của bạn |
session_name | string | Không | - | Tên hiển thị cho phiên mới (tối đa 200 ký tự) |
ephemeral | boolean | Không | false | Yêu cầu một lần chỉ truyền phát trực tuyến. Không trả về ID phiên, không thể tiếp tục, và dữ liệu sẽ bị xóa ngay sau khi yêu cầu hoàn tất |
stream | boolean | Không | true | true để truyền phát trực tuyến qua SSE, false để dùng JSON. Việc cấp quyền MCP yêu cầu phải truyền phát trực tuyến |
include_progress | boolean | Không | true | Đặt thành false để bỏ qua các sự kiện stream_progress. Chỉ áp dụng khi truyền phát trực tuyến |
model | string | Không | - | Ghi đè mô hình một lần chỉ cho yêu cầu này. Sử dụng một ID mô hình ổn định như claude-sonnet-5. Không thay đổi mô hình mặc định của phiên |
additional_context | object[] | Không | - | Ngữ cảnh có tên chỉ dành cho yêu cầu này. Xem Ngữ cảnh bổ sung |
Ví dụ - Truyền phát trực tuyến (mặc định)
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"
}'
Phản hồi là một luồng SSE (xem Truyền phát trực tuyến (SSE) để biết định dạng sự kiện). Các yêu cầu lâu dài bao gồm session_id mới; các yêu cầu ephemeral: true không có session_id và phải sử dụng truyền phát trực tuyến.
Ví dụ - JSON (không truyền phát trực tuyến)
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
}'
Phản hồi
Các phản hồi truyền phát trực tuyến phát ra các sự kiện SSE được mô tả trong Truyền phát trực tuyến (SSE). Các phản hồi không truyền phát trực tuyến trả về đối tượng tin nhắn kèm stop_reason và usage cho yêu cầu, như được trình bày trong Tiếp tục Phiên. stop_reason là end_run, hoặc user_cancelled nếu lượt chạy bị hủy sau khi tác nhân đã tạo ra tin nhắn.
Nếu lượt chạy bị hủy trước khi tác nhân tạo ra tin nhắn, API trả về 200 OK với status: "cancelled", session_id, run_id, stop_reason: "user_cancelled", và usage.
Nếu một lượt chạy không truyền phát trực tuyến vẫn đang được xử lý sau 90 giây, API sẽ trả về 202 Accepted với status: "processing", session_id, run_id, và một message dạng văn bản dễ đọc. Lượt chạy tiếp tục sau khi phản hồi được gửi hoặc khi client ngắt kết nối; hãy kiểm tra các tin nhắn của phiên, hoặc sử dụng truyền phát trực tuyến cho các luồng công việc dài hơn.
Lỗi
| Trạng thái | Mã | Điều kiện |
|---|---|---|
| 400 | missing_required_field | Trường agent là bắt buộc |
| 400 | invalid_payload | JSON không hợp lệ hoặc một trường có loại dữ liệu không hợp lệ |
| 400 | bad_request | Chế độ ephemeral không hợp lệ, additional_context không hợp lệ, hoặc user/session_name vượt quá độ dài tối đa |
| 400 | content_or_uploaded_files_required | Không cung cấp content cũng không cung cấp file_urls |
| 400 | content_too_long | Nội dung tin nhắn vượt quá 32.000 token |
| 400 | exceed_max_upload_files | Có nhiều hơn 10 URL tệp khác nhau trong một yêu cầu duy nhất |
| 400 | unsupported_file_format | Một URL tệp có phần mở rộng tệp không được hỗ trợ |
| 400 | invalid_file_url | Một URL tệp có định dạng không hợp lệ hoặc không phải HTTPS |
| 400 | invalid_model_selection | model không phải là ID mô hình hợp lệ, hoặc mô hình mặc định của tác nhân không khả dụng |
| 402 | insufficient_credits | Không đủ tín dụng để tạo phiên hoặc gửi tin nhắn |
| 404 | agent_not_found | Tác nhân không tồn tại hoặc không thể truy cập được đối với tài khoản của bạn |
Tiếp tục Phiên
POST /sessions/{session_id}/messages
Gửi một tin nhắn đến một phiên liên tục hiện có và nhận phản hồi từ tác nhân. Theo mặc định, phản hồi được truyền phát trực tuyến qua SSE; đặt stream: false để nhận JSON.
Nội dung yêu cầu
| Trường | Loại | Bắt buộc | Mặc định | Mô tả |
|---|---|---|---|---|
content | string | Có điều kiện | - | Nội dung tin nhắn. Bắt buộc trừ khi file_urls được cung cấp |
file_urls | string[] | Có điều kiện | - | URL của các tệp cần đính kèm. Bắt buộc trừ khi content được cung cấp |
stream | boolean | Không | true | true để truyền phát trực tuyến qua SSE, false để nhận JSON. Xác thực MCP yêu cầu truyền phát trực tuyến |
include_progress | boolean | Không | true | Đặt thành false để bỏ qua các sự kiện stream_progress. Chỉ áp dụng khi truyền phát trực tuyến |
model | string | Không | - | Ghi đè mô hình một lần chỉ áp dụng cho yêu cầu này. Sử dụng một ID mô hình ổn định như claude-sonnet-5. Không làm thay đổi mô hình mặc định của phiên |
additional_context | object[] | Không | - | Ngữ cảnh có tên chỉ dành cho yêu cầu này. Xem Ngữ cảnh bổ sung |
Ví dụ - Truyền phát trực tuyến (mặc định)
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?"
}'
Ví dụ - JSON (không truyền phát trực tuyến)
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
}'
Phản hồi 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"
}
}
Nếu phiên đã có một lượt chạy đang hoạt động hoặc tin nhắn đang chờ xử lý, API trả về JSON 202 Accepted với status: "queued", session_id, run_id, và message_id. Tin nhắn của người dùng sẽ được xử lý bởi lượt chạy đang hoạt động. Thay vào đó, yêu cầu có additional_context sẽ trả về 409 busy.
Các phản hồi không truyền phát trực tuyến tuân theo cùng quy tắc như Gửi Tin nhắn, bao gồm phản hồi status: "cancelled" khi lượt chạy bị hủy trước khi tác nhân tạo ra tin nhắn.
Lỗi
| Trạng thái | Mã | Điều kiện |
|---|---|---|
| 400 | invalid_payload | JSON không hợp lệ hoặc một trường có loại không hợp lệ |
| 400 | bad_request | additional_context không hợp lệ |
| 400 | content_or_uploaded_files_required | Không có content hoặc file_urls được cung cấp |
| 400 | content_too_long | Nội dung tin nhắn vượt quá 32.000 token |
| 400 | exceed_max_upload_files | Có hơn 10 URL tệp khác nhau trong một yêu cầu |
| 400 | unsupported_file_format | Một URL tệp có phần mở rộng tệp không được hỗ trợ |
| 400 | invalid_file_url | Một URL tệp không hợp lệ hoặc không phải HTTPS |
| 400 | invalid_model_selection | model không phải là ID mô hình hợp lệ, hoặc mô hình của phiên không còn khả dụng |
| 402 | insufficient_credits | Không đủ tín dụng để gửi tin nhắn |
| 404 | session_not_found | Phiên không tồn tại |
| 404 | session_not_owned | Phiên thuộc về một nhà phát triển khác hoặc không khớp với user được cung cấp |
| 409 | busy | Phiên tạm thời không khả dụng vì có một bản cập nhật khác đang được thực hiện, hoặc additional_context được gửi khi phiên đang có lượt chạy hoạt động hoặc tin nhắn đang chờ xử lý |
| 429 | too_many_pending | Phiên đã có 200 tin nhắn đang chờ xử lý |
| 503 | service_unavailable | Dịch vụ tạm thời không khả dụng |
Tính bất biến (Idempotency)
POST /messages, POST /sessions/{session_id}/messages và POST /invoke chấp nhận tiêu đề Idempotency-Key tùy chọn (tối đa 255 ký tự). Hãy sử dụng một khóa duy nhất cho mỗi lần gửi hợp lệ của người dùng để việc thử lại mạng hoặc gửi trùng lặp không tạo ra các lượt chạy trùng lặp. Các khóa được lưu giữ trong 24 giờ.
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"
}'
Không truyền phát trực tuyến: Việc thử lại sẽ trả về phản hồi đã được lưu kèm theo tiêu đề Idempotent-Replayed: true, bao gồm cả các lỗi được trả về sau khi yêu cầu đã bắt đầu được xử lý. Phản hồi 202 Accepted đã lưu sẽ được phát lại nguyên trạng; hãy sử dụng Lấy Trạng thái Lượt chạy hoặc Danh sách Tin nhắn để kiểm tra kết quả. Các yêu cầu bị từ chối trước khi bắt đầu xử lý, chẳng hạn như lỗi kiểm tra hợp lệ hoặc lỗi tín dụng, sẽ không được lưu, vì vậy lần thử lại sẽ được đánh giá lại.
Truyền phát trực tuyến: Luồng dữ liệu không được phát lại. Đối với POST /messages và POST /sessions/{session_id}/messages, việc thử lại trong khi đang chạy hoặc sau khi hoàn tất sẽ trả về một lỗi bất biến cùng với run_id gốc và, đối với các yêu cầu lưu trữ lâu dài, session_id. Đối với các yêu cầu lưu trữ lâu dài, hãy sử dụng Lấy Trạng thái Lượt chạy để kiểm tra một lượt chạy đang hoạt động, hoặc Danh sách Tin nhắn để lấy các kết quả đã được lưu trữ. Kết quả POST /invoke dạng truyền phát trực tuyến không thể truy xuất sau khi luồng đóng. Các lần thử lại POST /invoke trả về id ban đầu thay vì run_id và session_id.
Ví dụ về việc thử lại truyền phát trực tuyến đã hoàn tất:
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"
}
}
Lỗi bất biến
| Trạng thái | Mã | Điều kiện |
|---|---|---|
| 400 | bad_request | Idempotency-Key vượt quá độ dài tối đa |
| 409 | idempotency_key_reused | Cùng một khóa đã được sử dụng với một yêu cầu khác |
| 409 | idempotency_key_in_use | Yêu cầu gốc vẫn đang chạy |
| 409 | idempotency_key_reused | Yêu cầu truyền phát trực tuyến gốc đã hoàn tất và không thể phát lại |
Danh sách Tin nhắn
GET /sessions/{session_id}/messages
Trả về danh sách phân trang các tin nhắn của phiên. Theo mặc định, chỉ các tin nhắn hội thoại external được trả về. Trang đầu tiên chứa các tin nhắn mới nhất; trong mỗi trang, các tin nhắn được sắp xếp theo thứ tự thời gian (cũ nhất trước). sequence là số thứ tự của tin nhắn trong phạm vi phiên.
Tham số truy vấn
| Tham số | Loại | Mặc định | Tối đa | Mô tả |
|---|---|---|---|---|
limit | integer | 20 | 100 | Số tin nhắn mỗi trang |
cursor | string | - | - | Con trỏ phân trang |
include | string | external | - | Các loại tin nhắn cần trả về: external, internal, hoặc all |
Ví dụ
curl "https://api.jenova.ai/v1/sessions/ses_abc123/messages?limit=50" \
-H "Authorization: Bearer jnv_sk_xxx"
Phản hồi 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
}
Đối tượng tin nhắn
| Trường | Loại | Mô tả |
|---|---|---|
id | string | ID tin nhắn (tiền tố msg_) |
session_id | string | ID phiên cha |
sequence | integer | Số thứ tự trong phạm vi phiên. Các số có thể được dùng lại sau khi tin nhắn bị xóa |
from | object | Đối tượng người gửi với type (user hoặc agent) và name |
type | string | external đối với tin nhắn hội thoại, hoặc internal đối với các bước làm việc của tác nhân |
time | string | Mốc thời gian ISO 8601 |
content | string | Nội dung văn bản. Có mặt trên các tin nhắn external |
model | string | ID mô hình ổn định đã tạo ra phản hồi. Chỉ có mặt trên tin nhắn của tác nhân |
files | array | Các tệp được đính kèm hoặc tạo ra kèm theo tin nhắn. Xem Đối tượng tệp bên dưới. Bị lược bỏ khỏi Danh sách Tin nhắn và Lấy Tin nhắn khi tin nhắn không có tệp |
stop_reason | string | Có mặt trên các tin nhắn external của tác nhân có nội dung. Giá trị là end_run |
agent | string | Slug của tác nhân thực thi, khi có |
agent_name | string | Tên hiển thị của tác nhân thực thi, khi có |
progress_events | array | Hoạt động được ghi lại cho một tin nhắn internal, khi có. Mỗi mục có cùng các trường như một sự kiện stream_progress |
Đối tượng tệp
| Trường | Loại | Mô tả |
|---|---|---|
file_id | string | ID tệp Jenova. Để trống khi không xác định |
name | string | Tên tệp |
url | string | URL tệp. Để trống khi không xác định |
format | string | Định dạng tệp viết thường, chẳng hạn pdf, png, hoặc csv |
size | integer | Kích thước tệp tính bằng byte. 0 khi không xác định |
Lỗi
| Trạng thái | Mã | Điều kiện |
|---|---|---|
| 400 | bad_request | Tham số truy vấn không hợp lệ |
| 404 | session_not_found | Phiên không tồn tại |
| 404 | session_not_owned | Phiên thuộc về nhà phát triển khác hoặc không khớp với user được cung cấp |
Lấy Tin nhắn
GET /sessions/{session_id}/messages/{message_id}
Truy xuất một tin nhắn đơn lẻ theo ID.
Tham số truy vấn
| Tham số | Loại | Mặc định | Mô tả |
|---|---|---|---|
include | string | external | Các loại tin nhắn có thể được trả về: external, internal, hoặc all |
Phản hồi 200 OK
Trả về một đối tượng tin nhắn đơn lẻ có cấu trúc giống với phản hồi danh sách.
Lỗi
| Trạng thái | Mã | Điều kiện |
|---|---|---|
| 400 | bad_request | Tham số truy vấn không hợp lệ |
| 404 | session_not_found | Phiên không tồn tại |
| 404 | session_not_owned | Phiên thuộc về nhà phát triển khác hoặc không khớp với user được cung cấp |
| 404 | not_found | Tin nhắn không tồn tại trong phiên này |
Tệp đính kèm
Truyền các URL HTTPS có thể truy cập công khai trong trường file_urls.
| Giới hạn | Giá trị |
|---|---|
| Số tệp tối đa mỗi tin nhắn | 10 |
| Kích thước tệp tối đa | 20 MB mỗi tệp |
Định dạng được hỗ trợ
- Hình ảnh: JPG, JPEG, PNG, WebP
- Tài liệu: PDF, DOCX, XLSX, PPTX, TXT, CSV, RTF, MD, HTML, XML, JSON, LOG
- Mã nguồn: JS, TS, TSX, JSX, PY, Java, Go, C, CPP, H, HPP, CS, RB, PHP, RS, Swift, KT, Scala, SQL, CSS, YAML, YML
URL tệp được tải về khi tác nhân đọc chúng trong lượt chạy, không phải khi yêu cầu được chấp nhận. URL không thể tải về, hoặc tệp lớn hơn 20 MB, sẽ không được đọc; bản thân yêu cầu không bị từ chối.
Khi liệt kê tin nhắn, các tệp đính kèm sẽ xuất hiện trong mảng files của tin nhắn.
Ngữ cảnh bổ sung
Truyền ngữ cảnh có tên cho một tin nhắn trong additional_context, chẳng hạn thông tin tài khoản của người dùng cuối. Ngữ cảnh này không được lưu vào lịch sử tin nhắn.
| Trường | Loại | Bắt buộc | Mô tả |
|---|---|---|---|
name | string | Có | Chữ thường, chữ số và dấu gạch dưới, bắt đầu bằng một chữ cái (tối đa 64 ký tự). Duy nhất trong yêu cầu, không tính dấu gạch dưới và dạng số nhiều |
content | string | Có | Nội dung ngữ cảnh. Không được để trống (tối đa 12.000 token) |
| Giới hạn | Giá trị |
|---|---|
| Số mục tối đa mỗi tin nhắn | 4 |
| Số token tối đa mỗi mục | 12.000 |
Hãy sử dụng một tên mang tính mô tả như customer_profile hoặc order_details.
Một mục thiếu name hoặc content, hoặc có giá trị không phải chuỗi, sẽ trả về 400 invalid_payload. Các mục không hợp lệ khác trả về 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 Phiên
Phiên là các cuộc hội thoại lâu dài giữa một người dùng cuối và một tác nhân. Hầu hết các tích hợp có thể tạo phiên một cách ngầm định bằng POST /messages.
Tạo Phiên
POST /sessions
Tạo một phiên bền vững trống được liên kết với một tác nhân cụ thể. Sử dụng thao tác này khi bạn cần một ID phiên trước tin nhắn đầu tiên; nếu không, hãy ưu tiên sử dụng POST /messages.
Lưu ý:
ephemeralkhông được chấp nhận trênPOST /sessions; hãy sử dụngPOST /messagesvớiephemeral: truecho các yêu cầu một lần.
Nội dung yêu cầu
| Trường | Loại | Bắt buộc | Mô tả |
|---|---|---|---|
agent | string | Có | Định danh slug của tác nhân |
user | string | Không | Định danh người dùng cuối bên ngoài của bạn (tối đa 255 ký tự). Nếu bỏ qua, giá trị mặc định sẽ là tài khoản nhà phát triển của bạn |
session_name | string | Không | Tên hiển thị cho phiên (tối đa 200 ký tự) |
Ví dụ
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"
}'
Phản hồi 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"
}
Đối tượng phiên
| Trường | Loại | Mô tả |
|---|---|---|
id | string | ID phiên (tiền tố ses_) |
session_name | string | Tên hiển thị |
agent | string | Slug của tác nhân |
agent_details | object | Thông tin chi tiết về tác nhân với display_name. Chỉ có mặt khi được yêu cầu bằng include=agent |
user | string | Định danh người dùng cuối. null nếu phiên được tạo mà không có user |
model | string | Mô hình được sử dụng khi tin nhắn không chỉ định mô hình. Được đặt thành mô hình mặc định của tác nhân khi phiên được tạo. Để trống khi tác nhân để Jenova tự chọn mô hình |
created_at | string | Mốc thời gian ISO 8601 |
updated_at | string | Mốc thời gian ISO 8601 |
Lỗi
| Trạng thái | Mã | Điều kiện |
|---|---|---|
| 400 | invalid_payload | JSON không hợp lệ hoặc một trường có loại dữ liệu không hợp lệ |
| 400 | missing_required_field | agent là trường bắt buộc |
| 400 | bad_request | ephemeral đã được cung cấp, hoặc user/session_name vượt quá độ dài tối đa |
| 402 | insufficient_credits | Không đủ tín dụng để tạo phiên |
| 404 | agent_not_found | Tác nhân không tồn tại hoặc tài khoản của bạn không có quyền truy cập |
Danh sách Phiên
GET /sessions
Trả về danh sách các phiên của bạn theo dạng phân trang, được sắp xếp theo thời điểm cập nhật gần nhất.
Tham số truy vấn
| Tham số | Loại | Mặc định | Tối đa | Mô tả |
|---|---|---|---|---|
limit | integer | 20 | 100 | Số mục trên mỗi trang |
cursor | string | - | - | Con trỏ phân trang |
user | string | - | - | Lọc theo định danh người dùng cuối (tối đa 255 ký tự) |
agent | string | - | - | Lọc theo slug của tác nhân |
include | string | - | - | Đặt thành agent để thêm agent_details vào mỗi phiên |
Ví dụ
curl "https://api.jenova.ai/v1/sessions?user=user_12345&limit=10" \
-H "Authorization: Bearer jnv_sk_xxx"
Phản hồi 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
}
Lỗi
| Trạng thái | Mã | Điều kiện |
|---|---|---|
| 400 | bad_request | Tham số truy vấn không hợp lệ |
Lấy Phiên
GET /sessions/{session_id}
Truy xuất một phiên đơn lẻ theo ID.
Tham số truy vấn
| Tham số | Loại | Mô tả |
|---|---|---|
include | string | Đặt thành agent để thêm agent_details vào phiên |
Phản hồi 200 OK
Trả về một đối tượng phiên.
Lỗi
| Trạng thái | Mã | Điều kiện |
|---|---|---|
| 400 | bad_request | Tham số truy vấn không hợp lệ |
| 404 | session_not_found | Phiên không tồn tại |
| 404 | session_not_owned | Phiên thuộc về một nhà phát triển khác hoặc không khớp với user được cung cấp |
Đổi tên Phiên
PATCH /sessions/{session_id}
Cập nhật tên hiển thị của một phiên.
Nội dung yêu cầu
| Trường | Loại | Bắt buộc | Mô tả |
|---|---|---|---|
session_name | string | Có | Tên hiển thị mới (tối đa 200 ký tự) |
Phản hồi 200 OK
Trả về đối tượng phiên đã được cập nhật.
Lỗi
| Trạng thái | Mã | Điều kiện |
|---|---|---|
| 400 | invalid_payload | JSON không hợp lệ hoặc một trường có loại dữ liệu không hợp lệ |
| 400 | missing_required_field | session_name là bắt buộc |
| 400 | bad_request | session_name vượt quá độ dài tối đa |
| 404 | session_not_found | Phiên không tồn tại |
| 404 | session_not_owned | Phiên thuộc về một nhà phát triển khác hoặc không khớp với user được cung cấp |
| 409 | busy | Phiên tạm thời không khả dụng vì có một bản cập nhật khác đang được thực hiện |
Xóa Phiên
DELETE /sessions/{session_id}
Xóa vĩnh viễn một phiên và toàn bộ tin nhắn của phiên đó. Phiên này không được có lượt chạy đang hoạt động.
Phản hồi 204 No Content
Lỗi
| Trạng thái | Mã | Điều kiện |
|---|---|---|
| 404 | session_not_found | Phiên không tồn tại |
| 404 | session_not_owned | Phiên thuộc về một nhà phát triển khác hoặc không khớp với user được cung cấp |
| 409 | busy | Phiên có lượt chạy đang hoạt động - hãy hủy lượt chạy đó trước |
Thao tác
Các điểm cuối này là các công cụ khôi phục và chỉnh sửa cho các phiên bền vững (persistent sessions). Hầu hết các tích hợp chỉ cần dùng Hủy Lượt chạy đang hoạt động; hãy sử dụng các thao tác khác khi bạn cố ý muốn thay đổi hoặc khôi phục trạng thái phiên. Tất cả các thao tác đều hỗ trợ cơ chế bảo vệ quyền sở hữu tùy chọn user được mô tả trong Người dùng cuối.
Hủy Lượt chạy đang hoạt động
POST /sessions/{session_id}/cancel
Hủy lượt chạy tác nhân đang hoạt động. Thao tác này không xóa các tin nhắn đã hoàn tất trước khi hủy.
Nội dung yêu cầu
| Trường | Loại | Bắt buộc | Mô tả |
|---|---|---|---|
run_id | string | Không | Cơ chế bảo vệ lượt chạy lỗi thời (stale-run) tùy chọn. Nếu được cung cấp và không khớp với lượt chạy đang hoạt động, API sẽ trả về 409 stale_run |
Phản hồi 204 No Content
Lỗi
| Trạng thái | Mã | Điều kiện |
|---|---|---|
| 400 | invalid_payload | JSON không hợp lệ hoặc một trường có loại dữ liệu không hợp lệ |
| 400 | cancel_not_allowed | Không có lượt chạy đang hoạt động để hủy, hoặc không được phép hủy |
| 404 | session_not_found | Phiên không tồn tại |
| 404 | session_not_owned | Phiên thuộc về một nhà phát triển khác hoặc không khớp với user được cung cấp |
| 409 | stale_run | run_id được cung cấp không khớp với lượt chạy đang hoạt động |
Hoàn tác Lượt chạy đang hoạt động
POST /sessions/{session_id}/undo
Hủy lượt chạy đang hoạt động, đợi cho lượt chạy đó dừng lại, sau đó xóa mọi tin nhắn mà nó đã thêm vào. Không có đầu ra bổ sung nào được lưu lại sau khi lệnh hoàn tác được thực hiện.
Nội dung yêu cầu
| Trường | Loại | Bắt buộc | Mô tả |
|---|---|---|---|
run_id | string | Không | Cơ chế bảo vệ lượt chạy lỗi thời (stale-run) tùy chọn. Nếu được cung cấp và không khớp với lượt chạy đang hoạt động, API sẽ trả về 409 stale_run |
Phản hồi 200 OK
{
"session_id": "ses_abc123",
"run_id": "run_abc123",
"deleted": ["msg_002", "msg_001"]
}
Nếu lượt chạy bị hủy trước khi bất kỳ tin nhắn nào được hoàn tất, deleted sẽ là một mảng trống.
Lỗi
| Trạng thái | Mã | Điều kiện |
|---|---|---|
| 400 | invalid_payload | JSON không hợp lệ hoặc một trường có loại dữ liệu không hợp lệ |
| 400 | cancel_not_allowed | Không có lượt chạy đang hoạt động để hoàn tác, hoặc không được phép hủy |
| 404 | session_not_found | Phiên không tồn tại |
| 404 | session_not_owned | Phiên thuộc về một nhà phát triển khác hoặc không khớp với user được cung cấp |
| 409 | stale_run | run_id được cung cấp không khớp với lượt chạy đang hoạt động |
| 409 | busy | Phiên tạm thời không khả dụng vì có một bản cập nhật khác đang được thực hiện |
Xóa Tin nhắn gần đây
POST /sessions/{session_id}/messages/delete
Xóa count tin nhắn gần đây nhất từ một phiên đang ở trạng thái nghỉ, bao gồm cả các tin nhắn internal. Sử dụng include=all trên Danh sách Tin nhắn để xem chúng. Phiên không được có lượt chạy đang hoạt động.
Nội dung yêu cầu
| Trường | Loại | Bắt buộc | Mô tả |
|---|---|---|---|
count | integer | Có | Số tin nhắn gần đây cần xóa tính từ cuối (phải lớn hơn 0). Giá trị lớn hơn 100 được xử lý như 100 |
Phản hồi 200 OK
{
"deleted": ["msg_002", "msg_001"]
}
Lỗi
| Trạng thái | Mã | Điều kiện |
|---|---|---|
| 400 | invalid_payload | JSON không hợp lệ hoặc một trường có loại dữ liệu không hợp lệ |
| 400 | bad_request | count bị thiếu, bằng 0, hoặc âm; hoặc không có tin nhắn nào để xóa |
| 404 | session_not_found | Phiên không tồn tại |
| 404 | session_not_owned | Phiên thuộc về một nhà phát triển khác hoặc không khớp với user được cung cấp |
| 409 | busy | Phiên có lượt chạy đang hoạt động |
Phân nhánh Phiên
POST /sessions/{session_id}/fork
Tạo một phiên mới bằng cách sao chép phiên nguồn cho đến một tin nhắn cụ thể. Phiên nguồn không được có lượt chạy đang hoạt động.
Nội dung yêu cầu (tùy chọn)
| Trường | Loại | Bắt buộc | Mô tả |
|---|---|---|---|
message_id | string | Không | ID tin nhắn tại điểm phân nhánh. Nếu bỏ qua, sẽ phân nhánh từ tin nhắn cuối cùng |
Phản hồi 201 Created
Trả về đối tượng phiên vừa được tạo với cấu trúc giống như khi tạo phiên.
Lỗi
| Trạng thái | Mã | Điều kiện |
|---|---|---|
| 400 | invalid_payload | JSON không hợp lệ hoặc một trường có loại dữ liệu không hợp lệ |
| 400 | bad_request | message_id không hợp lệ |
| 402 | insufficient_credits | Không đủ tín dụng để phân nhánh một phiên |
| 404 | not_found | message_id không tồn tại trong phiên này |
| 404 | session_not_found | Phiên không tồn tại |
| 404 | session_not_owned | Phiên thuộc về một nhà phát triển khác hoặc không khớp với user được cung cấp |
| 409 | busy | Phiên nguồn có lượt chạy đang hoạt động |
Lấy Trạng thái Lượt chạy
GET /sessions/{session_id}/runs/{run_id}
Trả về trạng thái hiện tại của một lượt chạy đang hoạt động. Sử dụng lệnh này sau khi kết nối SSE bị gián đoạn hoặc sau khi nhận được phản hồi idempotency có chứa run_id. Sau khi lượt chạy hoàn tất, hãy lấy kết quả bằng GET /sessions/{session_id}/messages.
Phản hồi 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 là running khi tác nhân đang làm việc, streaming khi văn bản phản hồi bắt đầu được tạo ra, hoặc ended trong thời gian ngắn sau khi lượt chạy kết thúc. Phản hồi cũng có thể bao gồm progress_events với hoạt động gần đây, theo cùng định dạng như stream_progress. Khi status là ended hoặc yêu cầu trả về 404 not_found, hãy lấy các tin nhắn của phiên.
Lỗi
| Trạng thái | Mã | Điều kiện |
|---|---|---|
| 404 | session_not_found | Phiên không tồn tại |
| 404 | session_not_owned | Phiên thuộc về một nhà phát triển khác hoặc không khớp với user được cung cấp |
| 404 | not_found | Lượt chạy này không đang hoạt động đối với phiên này |
Tín dụng
Lấy Số dư
GET /credits/balance
Trả về số dư tín dụng hiện tại của bạn.
Phản hồi 200 OK
{
"balance": "123.45"
}
API Tác nhân
Tạo và chỉnh sửa các tác nhân tùy chỉnh trong bảng điều khiển. Hỗ trợ API cho việc tạo và chỉnh sửa tác nhân sẽ sớm ra mắt.
Các luồng công việc theo lịch/nền hiện chưa được hỗ trợ qua API. Hỗ trợ sẽ sớm ra mắt.
Danh sách Tác nhân
GET /agents
Trả về các tác nhân khả dụng cho tài khoản của bạn. Sử dụng giá trị agent khi tạo phiên hoặc gửi tin nhắn.
Phản hồi 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"
}
]
}
| Trường | Loại | Mô tả |
|---|---|---|
agent | string | Slug ổn định của tác nhân để truyền vào giá trị agent |
display_name | string | Tên hiển thị thân thiện với con người |
description | string | Mô tả tác nhân |
Mô hình
Danh sách Mô hình
GET /models
Trả về tất cả các mô hình khả dụng để sử dụng trong trường model khi gửi tin nhắn hoặc gọi POST /invoke.
Phản hồi 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"
}
]
}
| Trường | Loại | Mô tả |
|---|---|---|
id | string | Định danh mô hình ổn định. Truyền giá trị này vào trường model trong Gửi Tin nhắn hoặc Gọi Mô hình |
name | string | Tên hiển thị thân thiện với con người |
thinking_variant | string | ID mô hình của biến thể suy luận/tư duy. Chỉ xuất hiện trên các mô hình cơ sở hỗ trợ suy luận |
Các mô hình có thinking_variant hỗ trợ suy luận mở rộng. Sử dụng trực tiếp ID biến thể trong trường model để bật tính năng này.
Nếu không có model nào được chỉ định khi gửi tin nhắn, model của phiên sẽ được sử dụng. Giá trị này được đặt thành mô hình mặc định của tác nhân khi phiên được tạo.
Gọi Mô hình
POST /invoke
Gửi lời nhắc trực tiếp đến mô hình, không qua tác nhân, phiên hay công cụ. Theo mặc định, phản hồi được truyền phát trực tuyến qua SSE; đặt stream: false để nhận JSON.
Nội dung yêu cầu
| Trường | Loại | Bắt buộc | Mặc định | Mô tả |
|---|---|---|---|---|
model | string | Có | - | ID mô hình từ Danh sách Mô hình |
content | string | Có | - | Lời nhắc, bao gồm mọi chỉ dẫn |
stream | boolean | Không | true | true để truyền phát trực tuyến qua SSE, false để dùng JSON |
user | string | Không | - | Định danh người dùng cuối bên ngoài của bạn (tối đa 255 ký tự). Nếu bỏ trống, giá trị mặc định sẽ là tài khoản nhà phát triển của bạn |
Ví dụ
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
}'
Phản hồi 200 OK
{
"id": "inv_abc123",
"model": "claude-sonnet-5",
"content": "Sunlight filters through tall pines onto a quiet, mossy floor.",
"usage": {
"cost": "0.0004"
}
}
Phản hồi truyền phát trực tuyến gửi stream_started, sau đó gửi các sự kiện stream_delta khi mô hình tạo văn bản, và kết thúc bằng stream_ended, trong đó có usage. Nối các giá trị chunk_content theo thứ tự seq để tạo thành phản hồi được truyền phát trực tuyến. Nếu yêu cầu thất bại, stream_error được gửi trước stream_ended. Các sự kiện mang id thay cho session_id và run_id.
usage.cost là null khi không có thông tin chi phí. Nếu một yêu cầu không truyền phát trực tuyến thất bại sau khi lệnh gọi mô hình đã bắt đầu, phản hồi lỗi sẽ bao gồm các trường id và usage ở cấp cao nhất.
Các yêu cầu truyền phát trực tuyến bị giới hạn ở 120 phút. Các yêu cầu không truyền phát trực tuyến chờ kết quả tối đa 30 phút thay vì trả về 202 Accepted, và trả về lỗi nếu đến lúc đó kết quả vẫn chưa sẵn sàng.
Lỗi
| Trạng thái | Mã | Điều kiện |
|---|---|---|
| 400 | invalid_payload | JSON không hợp lệ hoặc một trường có loại dữ liệu không hợp lệ |
| 400 | missing_required_field | content là bắt buộc |
| 400 | content_too_long | Nội dung vượt quá 32.000 token |
| 400 | bad_request | user vượt quá độ dài tối đa |
| 400 | invalid_model_selection | Thiếu model hoặc không phải ID mô hình hợp lệ |
| 400 | content_policy_violation | Nhà cung cấp mô hình từ chối yêu cầu vì lý do chính sách nội dung |
| 400 | llm_context_limit_reached | Đầu vào vượt quá cửa sổ ngữ cảnh của mô hình |
| 402 | insufficient_credits | Không đủ tín dụng để gọi mô hình |
| 500 | internal_error | Lỗi máy chủ không mong đợi |
| 502 | llm_api_error | Lỗi từ nhà cung cấp mô hình hoặc API mô hình phía trên |
| 502 | llm_empty_response | Mô hình trả về phản hồi trống |
| 502 | llm_reasoning_limit_reached | Mô hình đạt giới hạn suy luận mà chưa tạo phản hồi |
| 502 | llm_generation_limit_reached | Mô hình đạt giới hạn tạo nội dung mà chưa tạo phản hồi |
| 503 | service_unavailable | Dịch vụ tạm thời không khả dụng |
Tài liệu
GET /docs?lang=en
GET /doc?lang=en
Trả về tài liệu tham khảo này dưới dạng Markdown. Sử dụng lang để chọn ngôn ngữ.
Truyền phát trực tuyến (SSE)
Khi stream bị bỏ qua hoặc là true (giá trị mặc định), các phản hồi tin nhắn được gửi dưới dạng Server-Sent Events. Sử dụng các sự kiện message_completed để xác định các tin nhắn đã sẵn sàng để lấy hoặc hiển thị.
Thời gian chờ: Các kết nối SSE duy trì mở cho đến khi lượt chạy kết thúc. Mỗi lượt chạy bị giới hạn ở 120 phút. Các yêu cầu tin nhắn không truyền phát trực tuyến chờ tối đa 90 giây, sau đó trả về 202 Accepted trong khi lượt chạy vẫn tiếp tục. Đối với POST /invoke không truyền phát trực tuyến, xem Gọi Mô hình.
Tiêu đề Kết nối
Các luồng tin nhắn đặt các tiêu đề sau:
Content-Type: text/event-stream
Cache-Control: no-cache
Connection: keep-alive
X-Accel-Buffering: no
X-Run-Id: run_abc123
X-Run-Id có sẵn trước khi sự kiện SSE đầu tiên xuất hiện. Các luồng POST /invoke không đặt X-Run-Id; hãy sử dụng id trong stream_started.
Kết nối lại và Khôi phục
Các luồng SSE không được phát lại. Nếu kết nối bị ngắt trên một yêu cầu bền vững, hãy sử dụng session_id và run_id đã ghi lại để khôi phục trạng thái:
curl "https://api.jenova.ai/v1/sessions/ses_abc123/runs/run_abc123" \
-H "Authorization: Bearer jnv_sk_xxx"
Nếu lượt chạy vẫn đang hoạt động, lệnh này trả về trạng thái hiện tại, văn bản một phần và tiến trình gần đây. Nếu trả về status: "ended" hoặc 404 not_found, nghĩa là lượt chạy không còn hoạt động; hãy lấy các tin nhắn của phiên để đối chiếu đầu ra đã hoàn tất:
curl "https://api.jenova.ai/v1/sessions/ses_abc123/messages?limit=20" \
-H "Authorization: Bearer jnv_sk_xxx"
Định dạng Khung
Mỗi khung SSE tuân theo định dạng chuẩn sau:
event: <event_type>
data: <json_payload>
Hai dấu xuống dòng kết thúc mỗi khung.
Các loại Sự kiện
Luồng bao gồm các sự kiện vòng đời, delta văn bản, suy nghĩ, tiến trình, cảnh báo, hoàn tất tin nhắn, kết nối MCP, lỗi, cuối cùng và ping. Một số loại sự kiện chỉ được gửi khi có liên quan.
Đối với các yêu cầu tạm thời (ephemeral: true), mọi Sự kiện SSE đều bỏ qua session_id. Chỉ sử dụng run_id để liên kết các Sự kiện trong luồng đó.
Để đối chiếu cuối cùng đối với các yêu cầu bền vững, hãy chờ stream_ended, sau đó gọi Danh sách Tin nhắn.
Các trường phổ biến trên các Sự kiện phạm vi lượt chạy:
| Trường | Mô tả |
|---|---|
session_id | ID Phiên. Bị bỏ qua đối với các luồng tạm thời. Ghi lại giá trị này từ stream_started để dùng cho các yêu cầu tiếp theo khi sử dụng POST /messages bền vững |
run_id | ID Lượt chạy hiện tại, khi có sẵn |
id | ID yêu cầu invoke (có tiền tố inv_). Chỉ có mặt trong các luồng POST /invoke, vốn không có session_id hay run_id |
stream_started
Được gửi một lần khi Lượt chạy bắt đầu.
| Trường | Mô tả |
|---|---|
agent | Slug Tác nhân của Phiên, khi có sẵn |
stream_delta
Được gửi liên tục khi Tác nhân tạo ra văn bản phản hồi hiển thị. Nối các giá trị chunk_content theo thứ tự seq để tạo thành phản hồi được truyền phát trực tuyến.
event: stream_delta
data: {"session_id":"ses_abc123","run_id":"run_abc123","chunk_content":"To reset your ","seq":1}
| Trường | Mô tả |
|---|---|
chunk_content | Đoạn văn bản |
seq | Số thứ tự đoạn tăng dần trong luồng |
stream_thinking
Được gửi liên tục khi Tác nhân phát ra đầu ra suy nghĩ. Sử dụng trường này cho một chỉ báo suy nghĩ riêng biệt hoặc chế độ xem theo dõi; không nối trường này vào văn bản phản hồi cuối cùng.
| Trường | Mô tả |
|---|---|
content | Đoạn văn bản suy nghĩ |
stream_progress
Báo cáo hoạt động hiển thị cho người dùng trong quá trình tạo, chẳng hạn như đọc tài liệu, tìm kiếm trên web hoặc chờ hành động của người dùng. Những sự kiện này dùng để hiển thị tạm thời trong UI; hãy bỏ qua các trường không xác định. Sử dụng các tin nhắn đã hoàn tất làm lịch sử tin nhắn có thẩm quyền.
Đặt include_progress: false trên một yêu cầu tin nhắn để chỉ bỏ qua stream_progress. Các Sự kiện vòng đời, ping, message_completed, lỗi, và các Sự kiện kết thúc vẫn được gửi khi phù hợp.
| Trường | Mô tả |
|---|---|
state | Trạng thái hoạt động: running, success, failed, hoặc skipped. Xử lý các giá trị không xác định một cách hợp lý |
label | Nhãn hoạt động dễ đọc |
Một số Sự kiện tiến trình có thể bao gồm url, file_name, hoặc server_name như các gợi ý hiển thị tùy chọn.
message_completed
Được gửi mỗi khi một Tin nhắn hoàn tất và sẵn sàng để lấy hoặc hiển thị.
Đây là một điểm mốc ranh giới, không phải toàn bộ đối tượng Tin nhắn. Hãy lấy Tin nhắn nếu bạn cần nội dung hoặc metadata.
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"}
| Trường | Mô tả |
|---|---|
message_id | ID Tin nhắn đã hoàn tất |
sequence | Số thứ tự trong Phiên |
from | Đối tượng người gửi với type (user hoặc agent) và name |
type | Loại Tin nhắn: external hoặc internal |
mcp_connection
Được gửi khi tác nhân cần người dùng cuối kết nối hoặc cấp quyền cho một hoặc nhiều máy chủ MCP trước khi có thể tiếp tục. Sự kiện này chỉ khả dụng ở chế độ streaming.
| Trường | Mô tả |
|---|---|
connection_server_list | Các máy chủ MCP cần hành động kết nối. Mỗi máy chủ bao gồm mcp_server_id, mcp_server_name, và auth_url tùy chọn |
user_action_deadline_unix | Mốc thời gian Unix khi hành động kết nối của người dùng hết hạn |
mcp_connection_resolved
Được gửi khi hành động kết nối MCP của người dùng đã được giải quyết hoặc đã hết hạn.
Không có trường bổ sung nào ngoài các trường phổ biến phạm vi lượt chạy.
warning
Được gửi cho các cảnh báo không nghiêm trọng trong một Lượt chạy.
| Trường | Mô tả |
|---|---|
message | Cảnh báo không nghiêm trọng dễ đọc |
code | Mã cảnh báo tùy chọn |
stream_error
Được gửi khi một Lượt chạy thất bại. Một Sự kiện stream_ended cuối cùng có thể theo sau với success: false và stop_reason: "error".
| Trường | Mô tả |
|---|---|
code | Mã lỗi |
message | Thông báo lỗi dễ đọc |
stream_ended
Được gửi một lần khi lượt chạy kết thúc. Đây là sự kiện cuối cùng của luồng.
event: stream_ended
data: {"session_id":"ses_abc123","run_id":"run_abc123","success":true,"stop_reason":"end_run","usage":{"cost":"0.0032"}}
Ví dụ lượt chạy bị hủy:
event: stream_ended
data: {"session_id":"ses_abc123","run_id":"run_abc123","success":false,"stop_reason":"user_cancelled","usage":{"cost":"0.0012"}}
| Trường | Mô tả |
|---|---|
success | Cho biết lượt chạy có hoàn thành thành công hay không |
stop_reason | Lý do kết thúc lượt chạy: end_run, user_cancelled, user_action_timeout, hoặc error |
usage | Đối tượng mức sử dụng cho yêu cầu này. cost luôn có mặt và là null khi không có thông tin chi phí |
ping
Các khung giữ kết nối được gửi mỗi 15 giây để tránh việc proxy/CDN hết thời gian chờ. Hãy bỏ qua các sự kiện này trong client của bạn.
Tích hợp Máy chủ MCP
Kết nối các Tác nhân của bạn với các công cụ bên ngoài qua Model Context Protocol (MCP):
- Máy chủ MCP do Jenova quản lý: các máy chủ do Jenova lưu trữ cho tìm kiếm, truy xuất nội dung, tạo tài liệu và các khả năng tích hợp sẵn khác
- Máy chủ MCP từ xa: các máy chủ MCP từ xa khác được cấu hình cho Tác nhân của bạn
Các máy chủ MCP phải được cấu hình trong bảng điều khiển khi tạo hoặc chỉnh sửa Tác nhân của bạn. Để sử dụng máy chủ MCP riêng của bạn, hãy thêm nó vào một Tác nhân tùy chỉnh, sau đó gọi Tác nhân đó qua API. API sẽ thực thi các Công cụ được bật trong cấu hình của Tác nhân; không cần thiết lập thêm trong các yêu cầu API.
Khi một Tác nhân sử dụng các Công cụ MCP trong khi phản hồi, các Sự kiện tiến trình sẽ được gửi trong luồng ngay khi chúng xảy ra:
event: stream_progress
data: {"session_id":"ses_...","run_id":"run_...","state":"running","label":"Searching Google"}
Nếu tác nhân cần người dùng cuối kết nối hoặc cấp quyền cho một máy chủ MCP trong quá trình chạy, các phản hồi streaming có thể bao gồm các sự kiện mcp_connection và mcp_connection_resolved. Hãy hiển thị danh sách máy chủ kết nối cho người dùng cuối của bạn và mở auth_url được cung cấp khi có. Giữ luồng SSE mở trong khi người dùng cuối kết nối hoặc cấp quyền cho máy chủ.
Sau khi cấp quyền, Jenova lưu trữ token, cửa sổ cấp quyền hiển thị trang hoàn tất, và cùng Lượt chạy đó tiếp tục tự động. Người dùng cuối không cần gửi lại Tin nhắn.
Nếu người dùng cuối không kết nối, cấp quyền, hoặc bỏ qua hay tắt lời nhắc trước user_action_deadline_unix, lượt chạy kết thúc với stop_reason: "user_action_timeout". Bạn cũng có thể hủy lượt chạy đang hoạt động bằng POST /sessions/{session_id}/cancel.
Lưu trữ auth_url ở phía client. Nếu client bị mất kết nối trong quá trình cấp quyền, URL vẫn còn hiệu lực cho đến user_action_deadline_unix. Đối với các yêu cầu bền vững, hãy kiểm tra lượt chạy bằng Lấy Trạng thái Lượt chạy, hoặc lấy các tin nhắn sau khi lượt chạy kết thúc.
Các yêu cầu không streaming (stream: false) không hỗ trợ hành động người dùng kết nối MCP; hãy dùng streaming cho các tác nhân có thể cần tương tác này.
Bỏ qua kết nối MCP
POST /sessions/{session_id}/mcp/connection/skip
Hủy một hành động người dùng kết nối MCP đang chờ xử lý và cho phép lượt chạy tiếp tục mà không có kết nối đó.
Để tắt các lời nhắc kết nối trong tương lai cho một máy chủ đối với cùng một người dùng cuối và tác nhân, hãy bao gồm mcp_server_id và mute. mute chấp nhận một khoảng thời gian như 30m, 24h, hoặc 7d, hoặc forever.
Nội dung yêu cầu
| Trường | Loại | Bắt buộc | Mô tả |
|---|---|---|---|
run_id | string | Có | ID lượt chạy đang hoạt động từ sự kiện mcp_connection |
mcp_server_id | string | Không | Bắt buộc khi dùng mute; sử dụng mcp_server_id từ sự kiện |
mute | string | Không | Một khoảng thời gian như 30m, 24h, hoặc 7d, hoặc forever |
Phản hồi 204 No Content
Luồng phát ra sự kiện mcp_connection_resolved, sau đó lượt chạy tiếp tục với cùng run_id.
Lỗi
| Trạng thái | Mã | Điều kiện |
|---|---|---|
| 400 | invalid_payload | JSON không hợp lệ hoặc một trường có loại dữ liệu không hợp lệ |
| 400 | bad_request | Thiếu run_id, không có lượt chạy đang hoạt động, hoặc không có kết nối MCP để bỏ qua |
| 400 | bad_request | mute không hợp lệ, thiếu mcp_server_id khi đã đặt mute, hoặc mcp_server_id không hợp lệ cho phiên này |
| 404 | session_not_found | Phiên không tồn tại |
| 404 | session_not_owned | Phiên thuộc về một nhà phát triển khác hoặc không khớp với user đã cung cấp |
| 409 | stale_run | run_id không khớp với Lượt chạy đang hoạt động |
Thanh toán
Mọi chi phí đều được trừ từ số dư Tín dụng dành cho nhà phát triển của bạn. Xem mức sử dụng và nạp thêm Tín dụng tại www.jenova.ai/platform.
Giá cả
| Thao tác | Chi phí |
|---|---|
| Tạo Phiên | $0.01 cố định cho mỗi Phiên bền vững được tạo bởi POST /sessions hoặc POST /messages |
| Nhân bản Phiên | $0.05 cố định, không tính thêm phí tạo Phiên riêng |
| Gửi Tin nhắn | Thay đổi (xem bên dưới) |
| Gọi Mô hình | Thay đổi, tùy theo mô hình và token |
Chi phí Tin nhắn phụ thuộc vào:
- Mô hình - các Mô hình khác nhau có chi phí trên mỗi token khác nhau
- Độ dài ngữ cảnh - Phiên dài hơn tiêu thụ nhiều token đầu vào hơn cho mỗi yêu cầu
- Độ phức tạp của quy trình làm việc - quy trình làm việc dài hơn và việc sử dụng Công cụ nhiều hơn (tìm kiếm web, tạo tệp, phân tích tài liệu) làm tăng tổng mức tiêu thụ token
Chi phí thực tế được trả về dưới dạng stream_ended.usage.cost đối với các yêu cầu Truyền phát trực tuyến và usage.cost đối với các yêu cầu JSON không truyền phát trực tuyến.
Tạm giữ Tín dụng
Mỗi yêu cầu POST /messages, POST /sessions/{session_id}/messages và POST /invoke sẽ đặt một khoản tạm giữ $0.50 trên số dư Tín dụng của bạn trước khi việc thực thi bắt đầu. Điều này nhằm dự trữ tiền cho yêu cầu. Một Tin nhắn được đưa vào hàng đợi của một Lượt chạy đang hoạt động (202 Accepted với status: "queued") không tạo ra khoản tạm giữ bổ sung; mức sử dụng của Lượt chạy đang hoạt động được kiểm tra dựa trên số dư còn lại của bạn.
Khi yêu cầu hoàn tất, khoản tạm giữ được quyết toán theo chi phí thực tế và phần chênh lệch được giải phóng. Nếu chi phí thực tế vượt quá khoản tạm giữ, phần chênh lệch cũng sẽ bị tính phí, vì vậy số dư của bạn có thể xuống dưới 0. Các yêu cầu bị hủy và thất bại chỉ bị tính phí cho mức sử dụng đã phát sinh. Nếu một yêu cầu thất bại trước khi đến được Mô hình, toàn bộ khoản tạm giữ sẽ được giải phóng.
Do có các khoản tạm giữ, số dư khả dụng của bạn có thể tạm thời hiển thị thấp hơn trong khi các yêu cầu đang xử lý. Bạn cần có ít nhất $0.50 trong số dư khả dụng cho một yêu cầu POST /sessions/{session_id}/messages, POST /messages tạm thời, hoặc POST /invoke. Một yêu cầu POST /messages bền vững cũng tạo ra một Phiên và cần ít nhất $0.51 để trang trải khoản tạm giữ cùng với phí tạo Phiên.
Giới hạn tốc độ
Mọi tài khoản nhà phát triển đều chịu ba chiều Giới hạn tốc độ:
| Chiều | Mặc định | Mô tả |
|---|---|---|
| RPM (Yêu cầu mỗi phút) | 200 | Cửa sổ cố định 60 giây |
| RPD (Yêu cầu mỗi ngày) | 10.000 | Cửa sổ cố định 24 giờ |
| Đồng thời | 10 | Số lượng yêu cầu đang xử lý và lượt chạy đang hoạt động đồng thời tối đa |
Một lượt chạy giữ slot đồng thời cho đến khi kết thúc, kể cả sau phản hồi 202 Accepted hoặc khi client ngắt kết nối. Một yêu cầu POST /invoke giữ slot cho đến khi hoàn tất, kể cả khi client ngắt kết nối.
Các yêu cầu GET và HEAD không tiêu thụ slot đồng thời. cancel, undo và mcp/connection/skip cũng không tiêu thụ slot đồng thời, vì vậy các thao tác này vẫn khả dụng khi tất cả slot đang được sử dụng. Các yêu cầu này vẫn được tính vào RPM và RPD.
Một giới hạn riêng theo từng IP là 1.200 yêu cầu mỗi 60 giây cũng áp dụng cho mọi yêu cầu và trả về cùng lỗi 429 rate_limit_exceeded.
Tiêu đề Phản hồi
Các phản hồi API đã xác thực bao gồm các tiêu đề giới hạn tốc độ:
| Tiêu đề | Mô tả |
|---|---|
X-RateLimit-Limit | Giới hạn RPM của bạn |
X-RateLimit-Remaining | Số yêu cầu còn lại trong khung thời gian một phút hiện tại |
X-RateLimit-Reset | Mốc thời gian Unix khi khung thời gian hiện tại được đặt lại |
Retry-After | Số giây cần chờ trước khi thử lại. Được gửi trên các phản hồi 429 rate_limit_exceeded và 503 write_freeze_active |
Khi vượt quá giới hạn hàng ngày, X-RateLimit-Limit, X-RateLimit-Remaining và X-RateLimit-Reset sẽ mô tả cửa sổ theo ngày thay vì cửa sổ theo phút.
Khi vượt quá giới hạn, API trả về 429 Too Many Requests:
{
"error": {
"code": "rate_limit_exceeded",
"message": "Rate limit exceeded. Please try again later."
}
}
Xử lý lỗi
Các lỗi HTTP tức thời và lỗi lượt chạy không truyền phát trực tuyến tuân theo một cấu trúc thống nhất:
{
"error": {
"code": "error_code_string",
"message": "Human-readable description"
}
}
Thông báo lỗi được bản địa hóa dựa trên lang hoặc Accept-Language (xem Bản địa hóa).
Các lỗi Lượt chạy truyền phát trực tuyến được gửi dưới dạng các sự kiện stream_error. Một lượt chạy thất bại vẫn có thể gửi một sự kiện stream_ended cuối cùng với success: false và stop_reason được thiết lập. Các lỗi Lượt chạy không truyền phát trực tuyến bao gồm một đối tượng usage ở cấp cao nhất; cost là null khi không có thông tin chi phí.
Các lỗi sau có thể xảy ra trên bất kỳ điểm cuối nào:
| Trạng thái | Mã | Điều kiện |
|---|---|---|
| 401 | invalid_api_key | Khóa API bị thiếu, không hợp lệ hoặc đã bị thu hồi |
| 402 | developer_not_activated | Tài khoản nhà phát triển của bạn chưa được kích hoạt. Hãy mua tín dụng trong bảng điều khiển để kích hoạt |
| 403 | developer_disabled | Tài khoản nhà phát triển của bạn đã bị vô hiệu hóa |
| 403 | forbidden | Các yêu cầu từ mạng này bị chặn |
| 413 | payload_too_large | Nội dung yêu cầu vượt quá 1 MiB |
| 429 | rate_limit_exceeded | Đã vượt quá giới hạn tốc độ. Xem Giới hạn tốc độ |
| 503 | write_freeze_active | Các yêu cầu ghi tạm thời bị vô hiệu hóa để bảo trì |
Các lỗi riêng của từng điểm cuối được ghi chú trực tiếp trong phần mô tả của mỗi điểm cuối.
Lỗi Lượt chạy sau khi Bắt đầu
Lỗi Lượt chạy xuất hiện sau khi một yêu cầu tin nhắn đã được chấp nhận. Ở chế độ truyền phát trực tuyến, chúng xuất hiện dưới dạng các sự kiện stream_error và có thể được theo sau bởi stream_ended với success: false. Ở chế độ không truyền phát trực tuyến, chúng được trả về dưới dạng phản hồi lỗi JSON kèm mã trạng thái HTTP dưới đây.
| Mã trạng thái HTTP không truyền phát trực tuyến | Mã | Điều kiện |
|---|---|---|
| 400 | content_policy_violation | Nhà cung cấp mô hình từ chối yêu cầu vì lý do chính sách nội dung |
| 400 | llm_context_limit_reached | Đầu vào vượt quá cửa sổ ngữ cảnh của mô hình |
| 404 | session_not_found | Phiên đã bị xóa trước khi lượt chạy có thể thực thi |
| 409 | busy | Phiên trở nên bận hoặc tạm thời không khả dụng trước khi lượt chạy có thể bắt đầu |
| 413 | total_image_size_exceeded | Tổng dung lượng hình ảnh vượt quá giới hạn kích thước cho mỗi yêu cầu của mô hình |
| 500 | internal_error | Lỗi lượt chạy không mong đợi |
| 500 | response_interrupted | Lượt chạy bị gián đoạn. Hãy gửi lại tin nhắn |
| 500 | response_interrupted_message_saved | Lượt chạy bị gián đoạn sau khi tin nhắn của bạn đã được lưu. Hãy lấy các tin nhắn của phiên trước khi gửi lại |
| 502 | llm_api_error | Lỗi từ nhà cung cấp mô hình hoặc API mô hình phía trên |
| 502 | llm_empty_response | Mô hình trả về phản hồi trống |
| 502 | llm_reasoning_limit_reached | Mô hình đạt giới hạn suy luận mà chưa tạo phản hồi |
| 502 | llm_generation_limit_reached | Mô hình đạt giới hạn tạo nội dung mà chưa tạo phản hồi |
Phân trang
Danh sách Phiên và Danh sách Tin nhắn sử dụng phân trang dựa trên con trỏ (cursor-based pagination):
{
"items": [],
"next_cursor": "2026-05-19T11:15:00Z|ses_abc123",
"has_more": true
}
| Tham số | Loại | Mặc định | Tối đa | Mô tả |
|---|---|---|---|---|
limit | integer | 20 | 100 | Số lượng mục trên mỗi trang |
cursor | string | - | - | Con trỏ ẩn từ next_cursor của lần trước |
Truyền next_cursor làm tham số truy vấn cursor để lấy trang tiếp theo, mã hóa URL cho giá trị này. Khi has_more là false, không còn kết quả nào nữa. limit nằm ngoài khoảng 1-100 hoặc con trỏ không hợp lệ sẽ trả về 400 bad_request.
Bản địa hóa
Tất cả các điểm cuối đều nhận tham số truy vấn tùy chọn lang để kiểm soát ngôn ngữ của thông báo lỗi và bất kỳ nội dung được bản địa hóa nào.
| Nguồn | Mức ưu tiên | Ví dụ |
|---|---|---|
Tham số truy vấn lang | Cao nhất | ?lang=zh |
Tiêu đề Accept-Language | Dự phòng | Accept-Language: ja |
| Mặc định | Thấp nhất | Tiếng Anh (en) |
Bạn có thể thêm ?lang=xx vào bất kỳ URL yêu cầu nào:
POST /sessions?lang=zh
GET /sessions/ses_abc123/messages?lang=ja
Ngôn ngữ được hỗ trợ: en, zh, ja, ko, es, fr, de, it, pt, ru, id, th, vi
Quyền riêng tư và Dữ liệu
Jenova không sử dụng các prompt API, đầu ra, lịch sử hội thoại, tệp đã tải lên, hướng dẫn tác nhân hoặc cơ sở kiến thức để huấn luyện các mô hình của Jenova.
Đối với các nhà cung cấp mô hình bên thứ ba, Jenova sử dụng các kênh API thương mại, cài đặt tài khoản, các cam kết hợp đồng hoặc các tùy chọn từ chối (opt-out) nhằm ngăn nội dung của khách hàng bị sử dụng để huấn luyện các mô hình của nhà cung cấp.
Jenova lưu trữ và xử lý dữ liệu API bằng cơ sở hạ tầng tại Hoa Kỳ. Các nhà cung cấp bên thứ ba có thể xử lý dữ liệu tại các khu vực pháp lý khác như được mô tả trong Chính sách Quyền riêng tư và Điều khoản Sử dụng.
Để biết đầy đủ chi tiết, hãy xem Điều khoản Sử dụng, Chính sách Quyền riêng tư, và Chính sách Sử dụng.
Hỗ trợ
- Bảng điều khiển: www.jenova.ai/platform
- Email: [email protected]