メインコンテンツへスキップ
Session は Agent の実行ワークスペースです。Agent のスナップショットを Environment、オプションのリソース、オプションの Vault 認証情報にバインドします。新しい Session は idle で開始し、イベントを送信すると処理が始まります。

Session の状態ライフサイクル

Session はステートマシンです。Session リソースの status フィールドは次のいずれかの値を取ります。
状態説明遷移先
idleSession はアイドルで、メッセージを受け取る準備ができているrunningreschedulingterminated
runningAgent がターンを処理中idlereschedulingterminated
rescheduling基盤ランタイムが再スケジュール中で、idle に戻るまで Session は利用不可idleterminated
terminatedSession は終了済み(終端状態)
status フィールド以外に、さらに 2 つのライフサイクルマーカーが現れます。
  • アーカイブ済み(Archived): 非 null の archived_at タイムスタンプで示されます。status の値自体は archived には変わりません — Session は引き続き読み取れますが、新しいイベントは拒否されます。
  • cancel レスポンス: POST /api/v1/cloud/sessions/{id}/cancel エンドポイントは常に固定のリテラル "status": "canceling" を含むボディを返します。これはレスポンスの形であって Session の status ではありません — 永続化された status はターンが中断されると idle に戻ります。
1

作成 → idle

新しい Session は idle で開始し、入力を待ちます。
2

idle → running

user.message イベントを送信すると、Session は running に移行します。
3

running → idle

ターンが完了すると、Session は idle に戻ります。ターンごとにこれを繰り返します。
4

running → idle(cancel 後)

実行中の Session をキャンセルするとターンが中断され、Session は idle に戻ります。cancel レスポンスボディは、永続化された status に関わらず固定の "status": "canceling" リテラルを使用します。Session は引き続き再利用できます。
5

rescheduling

ランタイムは Session の再スケジュール中に一時的に rescheduling へ移行する場合があります。復旧が完了すると idle に戻ります。
6

archived / terminated(終端状態)

アーカイブ(archived_at 経由)または終了によって Session は恒久的に終了します — 再開はできません。

Cancel のセマンティクス

  • idle への cancel: no-op。HTTP 200 を返し、status は idle のままです。
  • running への cancel: Agent を中断します。HTTP 202 を返します。Session は canceling に移行し、ターンが中断されると idle に戻ります。
  • cancel 後: Session は引き続き再利用できます — 次の user.message を送信すると新しいターンが開始します。
# 現在のターンをキャンセル
curl -s -X POST "https://api.qoder.com/api/v1/cloud/sessions/$SESSION_ID/cancel" \
  -H "Authorization: Bearer $QODER_PAT"
終端状態は archivedterminated のみです。キャンセルされた Session は常に idle に戻り、メッセージを受け取り続けられます。

running 状態の Session へのメッセージ送信(409 エラー)

現在 running の Session に user.message を送信すると、API は HTTP 409 を返します。
{
  "type": "error",
  "request_id": "cb80235f-76a2-4ff3-9e28-5aa2da12dc14",
  "error": {
    "type": "invalid_request_error",
    "message": "Session is currently processing a turn. Cancel the current turn or wait for completion."
  }
}
これは新規ユーザーが最も陥りやすい落とし穴です。次のメッセージを送信する前に必ず session.status_idle を待つか、先に現在のターンをキャンセルしてください。

Session を作成する

既存の agentenvironment_id を使って Session を作成します。
curl -s -X POST "https://api.qoder.com/api/v1/cloud/sessions" \
  -H "Authorization: Bearer $QODER_PAT" \
  -H "Content-Type: application/json" \
  -d '{
    "agent": {"id": "agent_019e390add9f7bac9b6cc806db46fcbd", "type": "agent", "version": 2},
    "environment_id": "env_019e2590d33f711fabf42f2857cecd8a",
    "title": "Code review session",
    "metadata": {"purpose": "review"}
  }'
作成レスポンスは Session オブジェクトです。agentenvironment_idstatusresourcesvault_idsdeployment_idoutcome_evaluationsstatsenvironment_variablesarchived_atcreated_atupdated_at を含みます。 environmentdelta_flush_interval_msmemory_store_idsvaults などのレガシーリクエストフィールドはサポートされません。environment_variables は再びサポートされています — JSON 文字列のリクエスト形式と検証ルールについては Session の作成を参照してください。

作成時にリソースをアタッチする

resources 配列でファイル、リポジトリ、Memory Store をアタッチします。
{
  "resources": [
    {
      "type": "file",
      "file_id": "file_019e5ce0bf307a1a8f952eb814aea3d5",
      "mount_path": "/data/input/spec.md"
    },
    {
      "type": "github_repository",
      "url": "https://github.com/your-org/your-repo",
      "mount_path": "/data/workspace/your-repo",
      "authorization_token": "ghp_xxxxxxxxxxxxxxxxxxxxxxxxxxxx"
    },
    {
      "type": "memory_store",
      "memory_store_id": "memstore_019eed05b61e78cea61bfd366e072878",
      "access": "read_write",
      "instructions": "Use this memory for long-lived project context."
    }
  ]
}
作成後にファイルを追加するには POST /api/v1/cloud/sessions/{session_id}/resources を使用します。現在の CAS では、作成後の追加は file リソースのみサポートしています。resource の list/get/update/delete エンドポイントを使って、リソースの確認、GitHub トークンのローテーション、リソースの削除を行えます。

メッセージを送信する

Events API を通じて user.message イベントを送信します。content は空でない content block の配列でなければなりません。
curl -s -X POST "https://api.qoder.com/api/v1/cloud/sessions/$SESSION_ID/events" \
  -H "Authorization: Bearer $QODER_PAT" \
  -H "Content-Type: application/json" \
  -d '{
    "events": [
      {
        "type": "user.message",
        "content": [
          {"type": "text", "text": "Review this repository and summarize the risks."}
        ]
      }
    ]
  }'
send-events エンドポイントは HTTP 200{"data":[...]} を返します。受け付けるクライアントイベントタイプは次のとおりです: user.messageuser.interruptuser.tool_confirmationuser.tool_resultuser.custom_tool_resultuser.define_outcomesystem.message

イベントを読み取る

ライブ更新にはイベントストリームを使用します。
curl -s -N "https://api.qoder.com/api/v1/cloud/sessions/$SESSION_ID/events/stream" \
  -H "Authorization: Bearer $QODER_PAT" \
  -H "Accept: text/event-stream"
ストリームは ideventdata を含む Server-Sent Events を出力します。stream エンドポイントは再接続時のリプレイ用に Last-Event-ID ヘッダーをサポートします。イベントタイプの query filter は現在サポートされていません。 増分ストリーミングイベントを受信するには、Session の作成時に incremental_streaming_enabled: true を設定します。これにより、ストリームは最終的な完全な agent.message の前に agent.message_startagent.content_block_delta および関連する増分イベントを含めることができます。クイックな検証フローについては Incremental streaming を参照してください。 履歴とページネーションには list エンドポイントを使用します。
curl -s "https://api.qoder.com/api/v1/cloud/sessions/$SESSION_ID/events?limit=20&order=desc" \
  -H "Authorization: Bearer $QODER_PAT"
list レスポンスは datanext_page を使用します。

Session の読み取りと更新

# 単一 Session を取得
curl -s "https://api.qoder.com/api/v1/cloud/sessions/$SESSION_ID" \
  -H "Authorization: Bearer $QODER_PAT"

# Session 一覧
curl -s "https://api.qoder.com/api/v1/cloud/sessions?limit=20" \
  -H "Authorization: Bearer $QODER_PAT"

# title、metadata、または Agent 構成(tools、MCP servers)を更新
curl -s -X POST "https://api.qoder.com/api/v1/cloud/sessions/$SESSION_ID" \
  -H "Authorization: Bearer $QODER_PAT" \
  -H "Content-Type: application/json" \
  -d '{"title":"Updated title","metadata":{"priority":"high"}}'
Session list は page / next_page ページネーションを使用し、agent_idagent_versiondeployment_idmemory_store_idstatusescreated_at[...] などのフィルターをサポートします。

Threads

Managed-agent Session は、コーディネータースレッドと子スレッドを持つことができます。Thread エンドポイントは公開の session_thread 形式を使用し、rolenameagent_idagent_versionstop_reason などのレガシースレッドフィールドは含みません。
curl -s "https://api.qoder.com/api/v1/cloud/sessions/$SESSION_ID/threads" \
  -H "Authorization: Bearer $QODER_PAT"
子スレッドは POST /api/v1/cloud/sessions/{session_id}/threads/{thread_id}/archive でアーカイブできます。現在の CAS では、コーディネーター/メインスレッドのアーカイブを要求すると 409 を返します。

ライフサイクル

Session を今後使用しない場合はアーカイブします。
curl -s -X POST "https://api.qoder.com/api/v1/cloud/sessions/$SESSION_ID/archive" \
  -H "Authorization: Bearer $QODER_PAT"
削除の確認が必要な場合は Session を削除します。
curl -s -X DELETE "https://api.qoder.com/api/v1/cloud/sessions/$SESSION_ID" \
  -H "Authorization: Bearer $QODER_PAT"
削除は次を返します。
{
  "id": "sess_019e3bb1e8c171fd9abbb1477ffb84cc",
  "type": "session_deleted"
}
cancel エンドポイントは {"id":"...","type":"session","status":"canceling"} を返します。キャンセル対象のアクティブなターンがある場合は 202 Accepted を、Session がすでに idle の場合は(no-op として)200 OK を返します。

マルチターン対話のワークフロー

Session はマルチターン対話をサポートします。推奨パターンは次のとおりです。
  1. user.message イベントを送信する。
  2. SSE ストリームで更新をリッスンする。
  3. session.status_idle イベントを待つ。
  4. 次の user.message を送信する。
#!/bin/bash
# マルチターン対話の例
BASE_URL="https://api.qoder.com/api/v1/cloud"
SESSION_ID="sess_019e5ce0bf9074b69c3481e93771a522"
HEADERS=(
  -H "Authorization: Bearer $QODER_PAT"
)

# 第 1 ターン: 要件を提示
curl -s -X POST "$BASE_URL/sessions/$SESSION_ID/events" \
  "${HEADERS[@]}" \
  -H "Content-Type: application/json" \
  -d '{"events": [{"type": "user.message", "content": [{"type": "text", "text": "Scaffold a Python Flask project."}]}]}'

# 処理完了を待つ(ポーリングまたは SSE リッスン)
sleep 30

# 第 2 ターン: 追加要件
curl -s -X POST "$BASE_URL/sessions/$SESSION_ID/events" \
  "${HEADERS[@]}" \
  -H "Content-Type: application/json" \
  -d '{"events": [{"type": "user.message", "content": [{"type": "text", "text": "Add unit tests and a CI configuration to the project."}]}]}'
次のメッセージを送信する前に必ず session.status_idle を待ってください。Session がまだ running の間にメッセージを送信すると HTTP 409 を返します。

ベストプラクティス

  1. Agent バージョンを固定する — 本番環境では常に {"id": ..., "type": "agent", "version": ...} で Session を作成し、Agent の更新によって Session の挙動が予期せず変わらないようにします。
  2. metadata を活用する — トレーサビリティとデバッグのために、業務コンテキスト(タスク ID、トリガー元など)を metadata フィールドに記録します。
  3. 早めにキャンセルする — 不要になった Session はキャンセルして計算リソースを解放します。

よくある質問

Q: running 状態の Session にメッセージを送るとどうなりますか? A: API は HTTP 409 を返し、type: "invalid_request_error" とメッセージ “Session is currently processing a turn. Cancel the current turn or wait for completion.” が含まれます。現在のターンをキャンセルするか、Session が idle に戻るのを待ってから次のメッセージを送信してください。 Q: キャンセル後も Session を使えますか? A: 使えます。cancel 後、Session は canceling から idle に戻ります。次の user.message を送信して対話を継続できます。終端状態は archivedterminated のみです。 Q: 完全な対話履歴を取得するには? A: GET /api/v1/cloud/sessions/{id}/events を使って、ユーザーメッセージと Agent 応答を含む Session のすべてのイベントを取得します。 Q: SSE が切断された後に再接続するには? A: SSE stream エンドポイントに再接続する際に Last-Event-ID ヘッダーを渡します。サーバーはその ID 以降のイベントをリプレイします。 Q: GET /api/v1/cloud/environments が空配列を返します。 A: Personal Access Token (PAT) が対象ワークスペースに必要な権限を持っているか確認してください。Environment のアクセス範囲は認証ユーザーの権限にスコープされます。

API リファレンス