Jenova エージェント API リファレンス
ベース URL: https://api.jenova.ai/v1
Authentication: Authorization ヘッダー内のBearer token
目次
- 概要
- クイックスタート
- 基本概念
- 認証
- APIエンドポイント
- ストリーミング (SSE)
- MCPサーバー連携
- 請求
- レート制限
- エラー処理
- ページネーション
- ローカライゼーション
- プライバシーとデータ
- サポート
概要
基盤となるスタックを自前で組み立てることなく、本番環境で使える AI エージェントを構築・実行できます。Jenova エージェント API は、コアとなる機能をすべて単一のマネージドサービスに統合しています。
フルエージェントスタック
- エージェントオーケストレーション: 統合されたオーケストレーション層が、複雑なワークフローにわたってモデル、ツール、メモリ、検索を調整します。
- メモリとコンテキスト: 無制限の会話メモリとコンテキストが、すべてのセッションに標準で組み込まれています。外部の状態管理は不要です。
- ツールとMCP: プラットフォームネイティブのツールおよび任意のリモートMCPサーバーとの無制限のツール連携が、すぐに利用できます。
- 任意のモデルを利用可能: OpenAI、Anthropic、Google、xAI、Qwenなどのモデルを、単一の連携でエージェントに活用できます。
- フルマネージドストレージ: RAGを組み込んだマネージド型のリレーショナルデータベースおよびベクトルデータベース。インフラのプロビジョニングやスケーリングは不要です。
- プロダクショングレード: 数十万人のユーザーに利用されています。フルマネージドインフラ、安定したAPI、本番トラフィックに対応した設計です。
クイックスタート
1. APIキーの取得
www.jenova.ai/platform の開発者ダッシュボードからAPIキーを生成します。キーは jnv_sk_* の形式で、Bearer tokenとして渡されます。
2. エージェントの選択または作成
プラットフォーム上のビルド済みエージェントを選択するか、指示、モデル設定、ナレッジベースファイル、ツール、MCPサーバーを備えたカスタムエージェントをダッシュボードで作成します。
3. 最初のメッセージの送信
セッションを作成し、1回の呼び出しでメッセージを送信します。
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"}}
後続のリクエストのために、stream_started から session_id を取得しておいてください。同期的なJSONレスポンスについては、メッセージの送信を参照してください。
基本概念
エージェント
APIを通じて開発者がやり取りするAIエージェントです。各エージェントには一意のslug(例:my-support-agent)があり、API呼び出しの agent の値として使用します。
- ビルド済み: プラットフォーム上の既存のエージェントから選択します。
- カスタム: ダッシュボードで、指示、モデル、ナレッジベース、ツール、MCPサーバーを指定して独自に設定します。
セッション
エンドユーザーとエージェントの間の、独立した会話スレッドです。
- 識別子: プレフィックス付きID(例:
ses_abc123) - 範囲: 同一のエージェントおよびエンドユーザーに対して複数のセッションが存在でき、それぞれが独立した会話状態を持ちます
- ライフサイクル: セッションはAPI経由で削除されるまで無期限に保持されます。ストレージを使用しない単発タスクの場合は、
ephemeral: trueを指定してPOST /messagesを使用してください - プラットフォームの分離: APIのセッションは、Jenovaウェブアプリ内の会話とは分離されています。エンドユーザー、セッション履歴、および請求は、APIとウェブアプリの間で独立しています。
メッセージ
セッションの会話履歴内の1件のエントリであり、Messagesエンドポイントから返されます。各メッセージには、type("user" または "agent")と name を含む構造化された from オブジェクトに加え、メッセージの type が含まれます。
external- チャットコンテンツとして表示されることを意図した会話メッセージです。internal- 実行中のツール呼び出しや検索など、エージェントの作業ステップを表す任意のメッセージです。
実行
メッセージを送信した際に作成される、単一のエージェント実行です。実行には run_id があり、アクティブな間はイベントをストリーミングする場合があり、1件以上の完了済みメッセージを生成します。各セッションでは、一度にアクティブな実行を1つのみ持つことができます。
エンドユーザー
user フィールドは、セッションを開発者のアプリケーション内のエンドユーザーに紐付けます。開発者の内部ユーザーIDやUUIDなど、安定した不透明なIDを使用してください。アプリケーションで必要としない限り、メールアドレスなどの個人情報の使用は避けてください。同じ user の値で作成されたセッションはグループ化され、ユーザー単位でのセッション一覧取得が可能になります。
user を省略すると、そのセッションは開発者のアカウントに紐付けられ、後からエンドユーザー単位での絞り込みができなくなります。本番環境では user を必ず渡してください。
既存セッションへのリクエストでは、user は任意の所有権チェックとして機能します。指定する場合は、そのセッションの作成時に使用された user の値と一致している必要があります。一致しない場合、APIは 404 session_not_owned を返します。GET および DELETE リクエストではクエリパラメータとして、POST および PATCH リクエストではJSONボディ内で送信してください。
認証
すべてのリクエストは、Authorization ヘッダーに Bearer token を付与して認証してください。
Authorization: Bearer jnv_sk_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
APIキーは開発者ダッシュボードから生成されます。
User-Agent は任意です。SDKが診断のために設定する場合がありますが、APIとしては必須ではありません。
キー形式: キーは接頭辞 jnv_sk_ で始まり、続いてbase62エンコードされたランダムな文字列が付きます。
制限: 各開発者アカウントは、最大10個のアクティブなAPIキーを持つことができます。
APIエンドポイント
メッセージ API
メッセージの送信は主要なAPIパスです。最初のメッセージには POST /messages を使用してください。これにより1回のリクエストでセッションが作成され、実行が開始されます。取得済みの session_id を継続する場合は POST /sessions/{session_id}/messages を使用してください。
メッセージの送信
POST /messages
永続的なセッションを作成し、最初のメッセージを1つのアトミックなリクエストで送信します。セッションやメッセージ履歴を保存せず、セッションIDも返さず、継続もできないストレージなしのストリーミング単発リクエストにする場合は、ephemeral: true を設定してください。
リクエストボディ
| フィールド | 型 | 必須 | デフォルト | 説明 |
|---|---|---|---|---|
agent | string | Yes | - | エージェントのスラッグ識別子 |
content | string | 条件付き | - | メッセージ本文。file_urls が指定されていない場合は必須 |
file_urls | string[] | 条件付き | - | 添付するファイルのURL。content が指定されていない場合は必須 |
user | string | No | - | 開発者側のエンドユーザー識別子(最大255文字)。省略した場合は開発者アカウントがデフォルトとして使用されます |
session_name | string | No | - | 新しいセッションの表示名(最大200文字) |
ephemeral | boolean | No | false | ストレージなし、ストリーミング専用の単発リクエスト。セッションやメッセージ履歴を保存せず、セッションIDも返さず、継続もできません |
stream | boolean | No | true | SSEストリーミングの場合は true、JSONの場合は false。MCP認可にはストリーミングが必要です |
model | string | No | - | このリクエストのみに適用される一時的なモデルの上書き。claude-sonnet-5 のような安定したモデルIDを使用してください。セッションのデフォルトモデルは変更されません |
例 - ストリーミング(デフォルト)
curl -N -X POST https://api.jenova.ai/v1/messages \
-H "Authorization: Bearer jnv_sk_xxx" \
-H "Content-Type: application/json" \
-d '{
"agent": "my-support-agent",
"user": "user_12345",
"content": "Hello, I need help with my account"
}'
レスポンスはSSEストリームです(イベント形式についてはストリーミング (SSE)を参照してください)。永続的なリクエストには新しい session_id が含まれますが、ephemeral: true のリクエストでは session_id が省略され、ストリーミングを使用する必要があります。
例 - JSON(非ストリーミング)
curl -X POST https://api.jenova.ai/v1/messages \
-H "Authorization: Bearer jnv_sk_xxx" \
-H "Content-Type: application/json" \
-d '{
"agent": "my-support-agent",
"user": "user_12345",
"content": "Hello, I need help with my account",
"stream": false
}'
レスポンス
ストリーミングレスポンスは、ストリーミング (SSE)で説明されているSSEイベントを送出します。非ストリーミングレスポンスは、完了したリクエストに対する stop_reason と usage を含む、セッションの継続で示されているJSONメッセージ形式を返します。
非ストリーミングの実行が90秒経過してもまだ処理中の場合、APIは 202 Accepted を返し、status: "processing"、session_id、run_id、message を含みます。実行はレスポンス後またはクライアント切断後も継続されます。セッションのメッセージを確認するか、長時間のワークフローにはストリーミングを使用してください。
エラー
| ステータス | コード | 条件 |
|---|---|---|
| 400 | missing_required_field | agent が必須です |
| 400 | invalid_payload | JSONの形式が不正、またはフィールドの型が無効です |
| 400 | bad_request | ephemeralモードが無効、または user/session_name が最大長を超えています |
| 400 | content_or_uploaded_files_required | content も file_urls も指定されていません |
| 400 | content_too_long | メッセージ本文が最大トークン長を超えています |
| 400 | exceed_max_upload_files | 1回のリクエストに10件を超えるファイルURLが指定されています |
| 400 | unsupported_file_format | ファイルURLの拡張子がサポートされていません |
| 400 | invalid_file_url | ファイルURLの形式が不正、またはHTTPSではありません |
| 400 | invalid_model_selection | モデルの上書き指定が有効な本番モデルではありません |
| 402 | insufficient_credits | セッションの作成またはメッセージの送信に必要なクレジットが不足しています |
| 404 | agent_not_found | エージェントが存在しない、または開発者のアカウントからアクセスできません |
セッションの継続
POST /sessions/{session_id}/messages
既存の永続セッションにメッセージを送信し、エージェントのレスポンスを受け取ります。レスポンスはデフォルトでSSE経由でストリーミングされます。JSONで受け取るにはstream: falseを設定してください。
リクエストボディ
| フィールド | 型 | 必須 | デフォルト | 説明 |
|---|---|---|---|---|
content | string | 条件付き | - | メッセージテキスト。file_urlsが指定されていない場合は必須 |
file_urls | string[] | 条件付き | - | 添付するファイルのURL。contentが指定されていない場合は必須 |
stream | boolean | 任意 | true | SSEストリーミングの場合はtrue、JSONの場合はfalse。MCPの認可にはストリーミングが必要 |
model | string | 任意 | - | このリクエストに限定した一時的なモデルの上書き。claude-sonnet-5などの安定したモデルIDを使用してください。セッションのデフォルトモデルは変更されません |
例 - ストリーミング(デフォルト)
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はstatus: "queued"、session_id、run_id、message_idを含むJSONの202 Acceptedを返します。ユーザーメッセージはアクティブな実行によって処理されます。
エラー
| ステータス | コード | 条件 |
|---|---|---|
| 400 | invalid_payload | JSONの形式が不正、またはフィールドの型が無効 |
| 400 | content_or_uploaded_files_required | contentもfile_urlsも指定されていない |
| 400 | content_too_long | メッセージ内容が最大token長を超えている |
| 400 | exceed_max_upload_files | 1回のリクエストで10件を超えるファイルURLが指定されている |
| 400 | unsupported_file_format | ファイルURLの拡張子がサポートされていない |
| 400 | invalid_file_url | ファイルURLの形式が不正、またはHTTPSでない |
| 400 | invalid_model_selection | モデルの上書き指定が有効な本番モデルではない |
| 402 | insufficient_credits | メッセージ送信に十分なクレジットがない |
| 404 | session_not_found | セッションが存在しない |
| 404 | session_not_owned | セッションが他の開発者に属している、または指定されたuserと一致しない |
冪等性
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 ヘッダー付きで返されます。
ストリーミング: ストリームは再生されません。実行中または完了後にリトライすると、元の 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"
}
}
冪等性エラー
| ステータス | コード | 条件 |
|---|---|---|
| 409 | idempotency_key_reused | 同一のキーが異なるリクエストで使用された |
| 409 | idempotency_key_in_use | 元のリクエストがまだ実行中である |
| 409 | idempotency_key_reused | 元のストリーミングリクエストは既に完了しており、再生できない |
メッセージ一覧の取得
GET /sessions/{session_id}/messages
表示可能な会話メッセージのページネーション付き一覧を返します。最初のページには最新のメッセージが含まれます。各ページ内では、メッセージは時系列順(古いものから新しいものへ)で並びます。sequence はセッション内での安定した並び順を示す番号です。
クエリパラメータ
| パラメータ | 型 | デフォルト | 最大 | 説明 |
|---|---|---|---|---|
limit | integer | 20 | 100 | 1ページあたりのメッセージ数 |
cursor | string | - | - | ページネーションカーソル |
例
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
}
メッセージオブジェクト
| フィールド | 型 | 説明 |
|---|---|---|
id | string | メッセージID(msg_ の接頭辞付き) |
session_id | string | 親セッションのID |
sequence | integer | セッション内での安定した並び順を示す番号 |
from | object | 送信者オブジェクト。type("user" または "agent")と name を含む |
type | string | メッセージの種類。表示可能な会話メッセージでは通常 external |
time | string | ISO 8601形式のタイムスタンプ |
content | string | テキスト内容。externalメッセージに存在します |
model | string | レスポンスを生成した安定的なモデルID。エージェントメッセージにのみ存在します |
files | array | メッセージに含まれる添付または生成されたファイル。各エントリには、判明している場合、file_id、name、url、format、size が含まれます |
stop_reason | string | 完了したエージェントメッセージに存在します。現在の値は end_run です |
agent | string | 実行したエージェントのslug(利用可能な場合) |
agent_name | string | 実行したエージェントの表示名(利用可能な場合) |
ファイルオブジェクト
| フィールド | 型 | 説明 |
|---|---|---|
file_id | string | Jenovaのファイルid(利用可能な場合) |
name | string | ファイル名 |
url | string | ファイルのURL(利用可能な場合) |
format | string | 小文字のファイル形式(pdf、png、csv など) |
size | integer | ファイルサイズ(バイト単位、判明している場合) |
エラー
| ステータス | コード | 条件 |
|---|---|---|
| 400 | bad_request | クエリパラメータが無効 |
| 404 | session_not_found | セッションが存在しない |
| 404 | session_not_owned | セッションが他の開発者に属している、または指定された user と一致しない |
メッセージの取得
GET /sessions/{session_id}/messages/{message_id}
IDを指定して、表示可能な単一のメッセージを取得します。
レスポンス 200 OK
一覧レスポンスと同じ構造の、単一のメッセージオブジェクトを返します。
エラー
| ステータス | コード | 条件 |
|---|---|---|
| 404 | session_not_found | セッションが存在しない |
| 404 | session_not_owned | セッションが他の開発者に属している、または指定された user と一致しない |
| 404 | not_found | このセッション内にメッセージが存在しない |
ファイル添付
公開アクセス可能なHTTPS URLを 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
特定のエージェントに紐づく空の永続セッションを作成します。最初のメッセージより前にセッションIDが必要な場合に使用します。それ以外の場合は POST /messages の利用を推奨します。
注記:
ephemeralはPOST /sessionsでは受け付けられません。保存を行わない単発のリクエストには、POST /messagesをephemeral: trueとともに使用してください。
リクエストボディ
| フィールド | 型 | 必須 | 説明 |
|---|---|---|---|
agent | string | 必須 | エージェントのslug識別子 |
user | string | 任意 | 開発者の外部エンドユーザー識別子(最大255文字)。省略した場合は開発者のアカウントがデフォルトになります |
session_name | string | 任意 | セッションの表示名(最大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"
}
エラー
| ステータス | コード | 条件 |
|---|---|---|
| 400 | invalid_payload | JSONが不正な形式である、またはフィールドの型が無効である |
| 400 | missing_required_field | agent は必須です |
| 400 | bad_request | ephemeral が指定された、または user/session_name が最大長を超えている |
| 402 | insufficient_credits | セッションを作成するためのクレジットが不足している |
| 404 | agent_not_found | エージェントが存在しない、または開発者のアカウントからアクセスできない |
セッション一覧の取得
GET /sessions
開発者のセッションのページネーションされた一覧を、最終更新日時の新しい順に返します。
クエリパラメータ
| パラメータ | 型 | 説明 |
|---|---|---|
limit | integer | 1ページあたりの件数(デフォルト20、最大100) |
cursor | string | ページネーションカーソル |
user | string | エンドユーザー識別子でフィルタ(最大255文字) |
agent | string | エージェントの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
}
エラー
| ステータス | コード | 条件 |
|---|---|---|
| 400 | bad_request | クエリパラメータが無効である |
セッションの取得
GET /sessions/{session_id}
IDを指定して単一のセッションを取得します。
レスポンス 200 OK
作成時のレスポンスと同じ構造のセッションオブジェクトを返します。
エラー
| ステータス | コード | 条件 |
|---|---|---|
| 404 | session_not_found | セッションが存在しない |
| 404 | session_not_owned | セッションが他の開発者に属している、または指定された user と一致しない |
セッションの名前変更
PATCH /sessions/{session_id}
セッションの表示名を更新します。
リクエストボディ
| フィールド | 型 | 必須 | 説明 |
|---|---|---|---|
session_name | string | Yes | 新しい表示名(最大200文字) |
レスポンス 200 OK
更新されたセッションオブジェクトを返します。
エラー
| ステータス | コード | 条件 |
|---|---|---|
| 400 | invalid_payload | JSONの形式が不正、またはフィールドの型が不正 |
| 400 | missing_required_field | session_name は必須です |
| 400 | bad_request | session_name が最大長を超えています |
| 404 | session_not_found | セッションが存在しません |
| 404 | session_not_owned | セッションが別の開発者に属している、または指定された user と一致しません |
セッションの削除
DELETE /sessions/{session_id}
セッションとそのすべてのメッセージを永久に削除します。セッションにアクティブな実行があってはいけません。
レスポンス 204 No Content
エラー
| ステータス | コード | 条件 |
|---|---|---|
| 404 | session_not_found | セッションが存在しません |
| 404 | session_not_owned | セッションが別の開発者に属している、または指定された user と一致しません |
| 409 | busy | セッションにアクティブな実行があります - 先にキャンセルしてください |
操作
これらのエンドポイントは、永続的なセッションに対する復旧および編集用のコントロールです。ほとんどの統合ではCancelのみで十分ですが、意図的にセッション状態を変更または復旧したい場合には、他の操作を使用してください。すべての操作は、エンドユーザー で説明されている任意の所有権ガード user をサポートします。
アクティブな実行のキャンセル
POST /sessions/{session_id}/cancel
現在進行中のエージェント実行をキャンセルします。キャンセル前に完了済みだったメッセージは削除されません。
リクエストボディ
| フィールド | 型 | 必須 | 説明 |
|---|---|---|---|
run_id | string | No | 古い実行を防ぐための任意のガードです。指定された値がアクティブな実行と一致しない場合、APIは 409 stale_run を返します |
レスポンス 204 No Content
エラー
| ステータス | コード | 条件 |
|---|---|---|
| 400 | cancel_not_allowed | キャンセル対象のアクティブな実行が存在しない、またはキャンセルが許可されていません |
| 404 | session_not_found | セッションが存在しません |
| 404 | session_not_owned | セッションが別の開発者に属している、または指定された user と一致しません |
| 409 | stale_run | 指定された run_id がアクティブな実行と一致しません |
アクティブな実行のアンドゥ
POST /sessions/{session_id}/undo
アクティブな実行をキャンセルし、停止を待ってから、その実行によって既に追加されたメッセージを削除します。アンドゥが発行された後は、追加の出力は保存されません。
リクエストボディ
| フィールド | 型 | 必須 | 説明 |
|---|---|---|---|
run_id | string | No | 古い実行を防ぐための任意のガードです。指定された値がアクティブな実行と一致しない場合、APIは 409 stale_run を返します |
レスポンス 200 OK
{
"session_id": "ses_abc123",
"run_id": "run_abc123",
"deleted": ["msg_002", "msg_001"]
}
いずれのメッセージも完了する前に実行がキャンセルされた場合、deleted は空の配列になります。
エラー
| ステータス | コード | 条件 |
|---|---|---|
| 400 | cancel_not_allowed | アンドゥ対象のアクティブな実行が存在しない、またはキャンセルが許可されていません |
| 404 | session_not_found | セッションが存在しません |
| 404 | session_not_owned | セッションが別の開発者に属している、または指定された user と一致しません |
| 409 | stale_run | 指定された run_id がアクティブな実行と一致しません |
| 409 | busy | 別の更新が進行中のため、セッションは一時的に利用できません |
直近のメッセージの削除
POST /sessions/{session_id}/messages/delete
アイドル状態のセッションから直近のN件のメッセージを削除します。セッションはアクティブな実行を持っていない必要があります。
リクエストボディ
| フィールド | 型 | 必須 | 説明 |
|---|---|---|---|
count | integer | Yes | 末尾から削除する直近のメッセージ数(0より大きい値である必要があります) |
レスポンス 200 OK
{
"deleted": ["msg_002", "msg_001"]
}
エラー
| ステータス | コード | 条件 |
|---|---|---|
| 400 | bad_request | count が未指定、ゼロ、または負の値である、あるいは削除対象のメッセージが存在しない |
| 404 | session_not_found | セッションが存在しない |
| 404 | session_not_owned | セッションが別の開発者に属している、または指定された user と一致しない |
| 409 | busy | セッションにアクティブな実行が存在する |
セッションのフォーク
POST /sessions/{session_id}/fork
元のセッションを指定したメッセージまでコピーして、新しいセッションを作成します。元のセッションはアクティブな実行を持っていない必要があります。
リクエストボディ
| フィールド | 型 | 必須 | 説明 |
|---|---|---|---|
message_id | string | No | フォーク元となるメッセージID。省略した場合は最後のメッセージからフォークされます |
レスポンス 201 Created
セッション作成時と同じ構造の、新しく作成されたセッションオブジェクトを返します。
エラー
| ステータス | コード | 条件 |
|---|---|---|
| 400 | bad_request | message_id が無効である |
| 402 | insufficient_credits | セッションをフォークするためのクレジットが不足している |
| 404 | not_found | message_id がこのセッション内に存在しない |
| 404 | session_not_found | セッションが存在しない |
| 404 | session_not_owned | セッションが別の開発者に属している、または指定された user と一致しない |
| 409 | busy | 元のセッションにアクティブな実行が存在する |
実行ステータスの取得
GET /sessions/{session_id}/runs/{run_id}
アクティブな実行の現在の状態を返します。SSE接続が切断された場合や、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"
}
実行がアクティブな間は、レスポンスに直近の進行状況のヒントが含まれる場合もあります。
エラー
| ステータス | コード | 条件 |
|---|---|---|
| 400 | bad_request | セッションが一時的(ephemeral)なものである |
| 404 | session_not_found | セッションが存在しない |
| 404 | session_not_owned | セッションが別の開発者に属している、または指定された user と一致しない |
| 404 | not_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"
}
]
}
| フィールド | 型 | 説明 |
|---|---|---|
agent | string | agent の値として渡す、変更されないエージェントのslug |
display_name | string | 人が読める形式の表示名 |
description | string | エージェントの説明 |
モデル
モデル一覧の取得
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"
}
]
}
| フィールド | 型 | 説明 |
|---|---|---|
id | string | 変更されないモデル識別子。Send Messageの model の値として渡します |
name | string | 人が読める形式の表示名 |
thinking_variant | string | 推論(thinking/reasoning)バリアントのモデルID。推論に対応するベースモデルにのみ存在します |
thinking_variant を持つモデルは、拡張推論に対応しています。これを有効にするには、model フィールドにバリアントIDを直接指定してください。
メッセージ送信時に 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>
2つの改行で各フレームが終端します。
イベントタイプ
ストリームには、ライフサイクル、テキスト差分、思考、進行状況、警告、メッセージ完了、MCP接続、エラー、最終、ping の各イベントが含まれます。一部のイベントタイプは、関連する場合にのみ送信されます。
エフェメラルリクエスト(ephemeral: true)の場合、すべてのSSEイベントでsession_idが省略されます。その1つのストリーム内でイベントを関連付けるには、run_idのみを使用してください。
永続的リクエストの最終的な整合性確認については、stream_endedを待ってから、List Messagesを呼び出してください。
実行スコープのイベントに共通するフィールド:
| フィールド | 説明 |
|---|---|
session_id | セッションID。エフェメラルストリームでは省略されます。永続的なPOST /messagesを使用する際、フォローアップリクエスト用にこの値をstream_startedから取得してください |
run_id | 現在の実行ID(利用可能な場合) |
stream_started
実行が開始されたときに一度送信されます。
| フィールド | 説明 |
|---|---|
agent | セッションエージェントのslug(利用可能な場合) |
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
エージェントが思考出力を発する間、繰り返し送信されます。これは、独立した思考インジケーターやトレース表示に使用してください。最終的な応答テキストに連結しないでください。
| フィールド | 説明 |
|---|---|
content | 思考テキストのチャンク |
stream_progress
ドキュメントの読み取り、Web検索、ユーザーアクション待ちなど、生成中にユーザーに表示するアクティビティを報告します。これらのイベントは一時的なUI表示を目的としています。不明なフィールドは無視してください。正式なメッセージ履歴には完了済みメッセージを使用してください。
高度な使い方: メッセージリクエストでは、stream_progressのみを省略するためにinclude_progress: falseを受け付けます。ライフサイクルイベント、ping、message_completed、エラー、終端イベントは、関連する場合には引き続き送信されます。
| フィールド | 説明 |
|---|---|
state | ライフサイクルの状態: running、in-progress、success、failed、skipped、complete、cancelledなど。未知の値も適切に処理してください |
label | 人間が読める活動ラベル |
一部の進行状況イベントには、任意の表示用ヒントとしてurl、file_name、server_nameが含まれる場合があります。
message_completed
メッセージが完了し、取得または表示できる状態になるたびに送信されます。
これは境界マーカーであり、完全なメッセージオブジェクトではありません。内容やメタデータが必要な場合は、メッセージを取得してください。
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_id | 完了したメッセージのID |
sequence | セッション内での安定した順序番号 |
from | 送信者オブジェクト。type(userまたはagent)とnameを含む |
type | メッセージタイプ: externalまたはinternal |
mcp_connection
エージェントが続行する前に、エンドユーザーが1つ以上のMCPサーバーへ接続または認可する必要がある場合に送信されます。このイベントはストリーミングモードでのみ利用できます。
| フィールド | 説明 |
|---|---|
connection_server_list | 接続アクションが必要なMCPサーバー。各サーバーには mcp_server_id、mcp_server_name、および任意の auth_url が含まれます |
user_action_deadline_unix | 接続ユーザーアクションの期限切れ時刻を表すUnixタイムスタンプ |
mcp_connection_resolved
MCP接続ユーザーアクションが解決された、または期限切れになった場合に送信されます。
共通の実行スコープフィールド以外の追加フィールドはありません。
warning
実行中の致命的でない警告に対して送信されます。
| フィールド | 説明 |
|---|---|
message | 人間が読める致命的でない警告 |
code | 任意の警告コード |
stream_error
実行が失敗したときに送信されます。続いて、success:falseおよびstop_reason:"error"を伴う最終的なstream_endedイベントが送信される場合があります。
| フィールド | 説明 |
|---|---|
code | エラーコード |
message | 人間が読めるエラーメッセージ |
stream_ended
実行が終了すると1回だけ送信されます。これはストリームの最後のイベントです。
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
プロキシ/CDNのタイムアウトを防ぐため、15秒ごとに送信されるキープアライブフレームです。クライアント側では無視してください。
MCPサーバー連携
Model Context Protocol (MCP) を介して、開発者のエージェントを外部ツールに接続できます。
- Jenova管理のMCPサーバー: 検索、コンテンツ取得、ドキュメント生成などの組み込み機能を提供する、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_id | string | Yes | mcp_connection イベントから取得したアクティブな実行ID |
mcp_server_id | string | No | mute を指定する場合は必須。イベントの mcp_server_id を使用します |
mute | string | No | 24h または forever |
レスポンス 204 No Content
ストリームは mcp_connection_resolved を発行し、その後、実行は同じ run_id のまま継続します。
エラー
| ステータス | コード | 条件 |
|---|---|---|
| 400 | bad_request | run_id がない、アクティブな実行がない、またはスキップするMCP接続がない |
| 400 | bad_request | mute の値が無効、または mute 指定時に mcp_server_id が欠落している |
| 404 | session_not_found | セッションが存在しない |
| 404 | session_not_owned | 指定された user と一致しない |
| 409 | stale_run | run_id がアクティブな実行と一致しない |
請求
すべてのコストは、開発者のクレジット残高から差し引かれます。使用量の確認とクレジットのチャージは www.jenova.ai/platform で行えます。
料金
| 操作 | コスト |
|---|---|
| セッションの作成 | POST /messages によって暗黙的に作成されるセッションを含め、持続的なセッションごとに一律 $0.01 |
| セッションのフォーク | 一律 $0.05 |
| メッセージの送信 | 可変(以下を参照) |
メッセージのコストは、以下の要素に依存します。
- モデル - モデルごとにトークン単価が異なります
- コンテキストの長さ - セッションが長くなるほど、1リクエストあたりの入力トークン消費量が増加します
- ワークフローの複雑さ - ワークフローが長くなったり、ツールの使用(Web検索、ファイル生成、文書解析)が増えると、トークンの総消費量が増加します
実際のコストは、ストリーミングリクエストでは stream_ended.usage.cost、非ストリーミングのJSONリクエストでは usage.cost として返されます。
クレジットホールド
新しいメッセージの実行ごとに、実行開始前に開発者のクレジット残高に対して**$0.50のホールド**が設定されます。これは実行のための資金を確保するものです。アクティブな実行中にキューに入れられたフォローアップメッセージでは、追加のホールドは発生しません。アクティブな実行の使用量は、開発者の残りの残高と照合されます。
実行が完了すると、ホールドは実際のコストで確定され、差額は解放されます。キャンセルまたは失敗した実行に対しては、すでに発生した使用量分のみが課金されます。リクエストがモデルに到達する前に失敗した場合、ホールドは全額解放されます。
つまり、リクエストの処理中は、利用可能な残高が一時的に低く表示される場合があります。既存のセッションへメッセージを送信する場合、または一時的なメッセージを送信する場合は、少なくとも**$0.50の利用可能な残高が必要です。持続的な POST /messages の最初のリクエストはセッションを作成するため、メッセージのホールドとセッション作成料をカバーするために少なくとも$0.51**が必要です。
レート制限
すべての開発者アカウントには、次の3つのレート制限の次元が適用されます。
| 次元 | デフォルト | 説明 |
|---|---|---|
| RPM(Requests Per Minute) | 60 | 1分単位の固定ウィンドウ |
| RPD(Requests Per Day) | 1,000 | 1日単位の固定ウィンドウ |
| 同時実行数 | 5 | 同時に処理中のリクエストの最大数 |
GET および HEAD リクエストは同時実行スロットを消費しません。cancel、undo、mcp/connection/skip も同時実行スロットを消費しないため、すべてのスロットが使用中でもこれらの操作は利用できます。これらのリクエストは引き続き RPM と RPD にカウントされます。
レスポンスヘッダー
認証済みのAPIレスポンスには、レート制限に関するヘッダーが含まれます。
| ヘッダー | 説明 |
|---|---|
X-RateLimit-Limit | 開発者のRPM制限 |
X-RateLimit-Remaining | 現在の1分間のウィンドウ内で残っているリクエスト数 |
X-RateLimit-Reset | 現在のウィンドウがリセットされるUnixタイムスタンプ |
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イベントとして配信されます。失敗した実行では、success:falseかつstop_reasonが設定された最終的なstream_endedイベントが送信される場合もあります。非ストリーミングの実行エラーには、コストデータが利用可能な場合、トップレベルのusageオブジェクトが含まれることもあります。
エンドポイント固有のエラーについては、各エンドポイントの説明内にドキュメント化されています。
開始後の実行エラー
実行エラーは、メッセージの実行がすでに開始された後に発生することがあります。ストリーミングモードでは、これらはstream_errorイベントとして表示され、その後にsuccess:falseを伴うstream_endedが続く場合があります。非ストリーミングモードでは、以下のHTTPステータスを伴うJSONエラーレスポンスとして返されます。
| 非ストリーミングHTTPステータス | コード | 説明 |
|---|---|---|
| 400 | content_policy_violation | モデルプロバイダーがコンテンツポリシー上の理由でリクエストを拒否しました |
| 404 | session_not_found | 実行が実行される前にセッションが削除されました |
| 409 | busy | 実行が開始される前にセッションがビジー状態または一時的に利用不可になりました |
| 413 | total_image_size_exceeded | 画像データの合計サイズがモデルの1リクエストあたりのサイズ制限を超えています |
| 500 | internal_error | 予期しない実行の失敗 |
| 502 | llm_api_error | モデルプロバイダーまたはアップストリームのモデルAPIエラー |
ページネーション
一覧取得系のエンドポイントはカーソルベースのページネーションを使用します。
{
"items": [],
"next_cursor": "eyJ2IjoxLCJrIjoiY3VyXzAyIn0",
"has_more": true
}
| パラメータ | 型 | デフォルト | 最大 | 説明 |
|---|---|---|---|---|
limit | integer | 20 | 100 | 1ページあたりの項目数 |
cursor | string | - | - | 前回のnext_cursorから取得したオペークなカーソル |
次のページを取得するには、next_cursorをcursorクエリパラメータとして渡してください。has_moreがfalseの場合、それ以上の結果はありません。
ローカライゼーション
すべてのエンドポイントは、エラーメッセージやローカライズされたコンテンツの言語を制御するための任意のlangクエリパラメータを受け付けます。
| 取得元 | 優先度 | 例 |
|---|---|---|
langクエリパラメータ | 最高 | ?lang=zh |
Accept-Languageヘッダー | フォールバック | Accept-Language: ja |
| デフォルト | 最低 | 英語(en) |
任意のリクエストURLに?lang=xxを追加できます。
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は、Jenovaのモデルの学習にAPIのプロンプト、出力、会話履歴、アップロードされたファイル、エージェントの指示、またはナレッジベースを使用することはありません。
サードパーティのモデルプロバイダーについては、Jenovaは、顧客のコンテンツがプロバイダーのモデルの学習に使用されないようにするための商用APIチャネル、アカウント設定、契約上の取り決め、またはオプトアウトを利用しています。
Jenovaは、米国のインフラストラクチャを使用してAPIデータを保存・処理します。サードパーティのプロバイダーは、プライバシーポリシーおよび利用規約に記載されているとおり、他の法域でデータを処理する場合があります。
詳細については、利用規約、プライバシーポリシー、使用ポリシーを参照してください。
サポート
- ダッシュボード: www.jenova.ai/platform
- メール: [email protected]