コンテンツにスキップ

エージェントの取り込み

ingest エンドポイントは、AI コーディングエージェント活動を エージェントセッションとして 取り込みます。エージェントとセッションごとに agent_entries の 1 行です。 エージェント は、Authorization: Bearer spantail_aat_… として渡す Agent Access Token(AAT) でこれらを書き込みます。

同じ agent_entries 行への書き込み経路は 2 つあり、1 つのセッションはちょうど一方からのみ供給されます。

  • POST /agent-entries — エージェントがクライアント側で計算したセッションサマリを投稿(例: Cursor)。
  • POST /agent-events — エージェントが生のターンごとのテレメトリを投稿し、サーバーがセッション エントリへロールアップ(例: Claude Code の Stop hook 経由)。

events 経路のセッションは、終了時に finalizePOST /agent-events/finalize)で確定情報を 補完できます。イベント由来のロールアップには手を触れず、エントリを補完するだけです。

読み取りは通常のユーザー資格情報(session または PAT)で行い、プロジェクト ACL に従います。

エージェントセッションオブジェクト

Section titled “エージェントセッションオブジェクト”
フィールド 説明
id string 一意の識別子。
workspaceId string 所属ワークスペース。
ownerUserId string エージェントが代わりに振る舞うユーザー。
projectId string | null セッションが記録されたプロジェクト。null はワークスペースレベルの作業、またはプロジェクト削除済み。
agentId string セッションを生成したエージェント。
sessionId string 外部セッション識別子(エージェント内での冪等キー)。
entryDate string ローカル日付 YYYY-MM-DD。読み取り時に閲覧者のタイムゾーンで startedAt から導出。
durationMinutes integer セッションの時間(分)。
usage object | null トークン使用量の合計(下記)。ソースが公開できない場合は null
context object | null usage 以外のセッションコンテキスト(下記)。キャプチャされていなければ null
eventCount integer | null ロールアップの計算に使われたイベント数。イベントを持たないサマリ経路のセッションでは null
description string | null 任意の短い要約(2000 文字以下)。
startedAt string | null ISO 8601 のセッション開始。
endedAt string | null ISO 8601 のセッション終了。
createdAt string ISO 8601 の作成時刻。
updatedAt string ISO 8601 の最終更新時刻。

usage オブジェクトはセッションのトークン合計を保持します。エージェントによって公開するバケットが 異なるため、必須は totalTokens のみです。

フィールド 必須 説明
totalTokens integer はい セッションの総トークン数。
inputTokens integer いいえ 入力トークン。
outputTokens integer いいえ 出力トークン。
cacheCreationTokens integer いいえ キャッシュ作成トークン。
cacheReadTokens integer いいえ キャッシュ読み取りトークン。
model string いいえ モデル名(100 文字以下)。
costUsd number いいえ USD でのコスト。ソースが提供する場合のみ(events 経路ではイベントごとのコストの合算)。

context オブジェクトはセッションの usage 以外のファセットを保持します。各ファセットは最大 20 個の 文字列(各 200 文字以下)のリストです。events 経路では models / branches / repositories を サーバーがイベントから導出し、refs は常にクライアントが与えます。

フィールド 説明
models string[] セッションで観測されたモデルの重複なしリスト(初出順)。
branches string[] git ブランチの重複なしリスト(イベント属性 vcs.ref.head.name 由来)。
repositories string[] リポジトリ URL の重複なしリスト(イベント属性 vcs.repository.url.full 由来)。
refs string[] クライアントが抽出した不透明な外部参照(例: github:owner/repo#123)。サーバーは形式を解釈しません。

POST /api/v1/agent-entries agent token

1 つのエージェントセッションを記録します。(agent, sessionId) で冪等です。同じセッションを 再送すると、重複を挿入せず行を更新するため、リトライやバッチ再集計で二重計上されません。

workspaceId は必須です。トークンはワークスペースを持たないため、指定のないペイロードは 400 で拒否されます(プラグインはリポジトリのリンクから解決します)。projectId には どこにも既定値はなく、省略するとワークスペースレベルの作業として記録されます。 entryDate は送りません。 読み取り時に startedAt から導出されます。startedAt を省略すると endedAt、次に ingest 時刻に フォールバックします。

リクエストボディ

フィールド 必須 説明
sessionId string はい 外部セッション id(1〜200 文字)。
durationMinutes integer はい セッションの時間(分、0 以上)。
workspaceId string はい 対象ワークスペース。指定のないペイロードは拒否されます。
projectId string いいえ 対象プロジェクト(ワークスペースに属すること)。ワークスペースレベルの作業では省略。
usage object いいえ トークン使用量の合計(上記)。
context object いいえ usage 以外のセッションコンテキスト(上記)。サマリ経路ではすべてのファセットをクライアントが与える。
description string いいえ 短い要約(2000 文字以下)。
startedAt string いいえ ISO 8601 のセッション開始。
endedAt string いいえ ISO 8601 のセッション終了(startedAt より前であってはならない)。
curl -X POST "https://<your-instance>/api/v1/agent-entries" \
  -H "Authorization: Bearer spantail_aat_youragenttoken" \
  -H "Content-Type: application/json" \
  -d '{
    "sessionId": "sess_8f21",
    "durationMinutes": 42,
    "projectId": "prj_site",
    "description": "Refactored the auth middleware",
    "usage": { "totalTokens": 18400, "inputTokens": 12000, "outputTokens": 6400 },
    "startedAt": "2026-06-28T09:00:00.000Z",
    "endedAt": "2026-06-28T09:42:00.000Z"
  }'

ターンごとのイベントの取り込み

Section titled “ターンごとのイベントの取り込み”

POST /api/v1/agent-events agent token

セッションの生のターンごとテレメトリを投稿します。アシスタントメッセージごとに 1 イベントです。 サーバーは新しいイベントを冪等に挿入し、サマリ経路が書き込むのと同じ agent_entries 行へ セッションのロールアップを再計算します。(agent, sourceId) で冪等です。累積トランスクリプトを 毎ターン再投稿しても安全で、既知のイベントは no-op となり、ロールアップは(加算ではなく) 再計算されるため、合計は収束します。

workspaceId はサマリ経路と同じく必須です。projectId にはどこにも既定値はありません (省略するとワークスペースレベルの作業として記録されます)。サマリ経路と同じライブの 委任チェックが適用されます。

リクエストボディ

フィールド 必須 説明
sessionId string はい 外部セッション id(1〜200 文字)。
events object[] はい ターンごとイベント 1〜5000 件(下記)。
workspaceId string はい 対象ワークスペース。指定のないペイロードは拒否されます。
projectId string いいえ 対象プロジェクト(ワークスペースに属すること)。

event は 1 つのアシスタントターン(1 API レスポンス、1 usage ブロック)です。

フィールド 必須 説明
sourceId string はい トランスクリプトのメッセージ id(1〜200 文字)。エージェント内での冪等キー。
timestamp string はい ISO 8601(UTC)のメッセージ時刻。
usage object はい エージェントのネイティブ usage オブジェクト。そのまま保存される。
model string いいえ モデル名(100 文字以下)。
operation string いいえ イベントが記録する操作。gen_ai.operation.name の語彙に準拠。既定は chat(1 推論ターン)。
costUsd number いいえ このターンの USD コスト。ソースが提供する場合のみ。セッションの usage.costUsd に合算される。
attributes object いいえ usage 以外のメタデータ。string/number/boolean の値を最大 20 件(文字列は 500 文字以下)。キーには対応する OTel 属性名がある場合はそれを使う。

推奨する attributes キー — サーバーが検証するのは上限であって名前ではないため、制限内であれば 何でも保存されます。以下はサーバーがエントリの context に集約するキーです。

キー 意味
vcs.ref.head.name エージェントが作業した git ブランチ。
vcs.repository.url.full リポジトリ URL(例: git remote get-url origin の出力)。
process.working_directory セッションの作業ディレクトリ。
app.version エージェントクライアントのバージョン。
request.id プロバイダのリクエスト id(トレーサビリティ用)。
curl -X POST "https://<your-instance>/api/v1/agent-events" \
  -H "Authorization: Bearer spantail_aat_youragenttoken" \
  -H "Content-Type: application/json" \
  -d '{
    "sessionId": "sess_8f21",
    "projectId": "prj_site",
    "events": [
      {
        "sourceId": "msg_01a",
        "timestamp": "2026-06-28T09:00:00.000Z",
        "model": "claude-opus-4",
        "usage": { "input_tokens": 8000, "output_tokens": 3200 },
        "attributes": { "vcs.ref.head.name": "feature/auth-refactor" }
      },
      {
        "sourceId": "msg_01b",
        "timestamp": "2026-06-28T09:12:00.000Z",
        "model": "claude-opus-4",
        "usage": { "input_tokens": 4000, "output_tokens": 3200 },
        "attributes": { "vcs.ref.head.name": "feature/auth-refactor" }
      }
    ]
  }'

POST /api/v1/agent-events/finalize agent token

events 経路 のセッションに、終了時の確定情報を補完します(例: Claude Code の SessionEnd hook から)。壁時計でのセッション終了時刻、要約、外部参照です。usage のロールアップはイベント 由来のまま変わりません。finalize がそれを変更することはなく、遅れて再送されたイベントが確定情報を 消すこともありません。endedAt がエントリを過去方向に動かすこともありません — セッションが開始前に 終わったり、記録済みの終了より前に戻ったりしないようクランプされます。

finalize はベストエフォートです。セッションのエントリがまだ存在しない場合(イベントが届いて いない場合)は 404 を返し、クライアントは単に無視して構いません。

リクエストボディ

フィールド 必須 説明
sessionId string はい 外部セッション id(1〜200 文字)。
workspaceId string はい 対象ワークスペース。指定のないペイロードは拒否されます。
endedAt string いいえ ISO 8601 の壁時計でのセッション終了。
description string いいえ セッションの要約(2000 文字以下)。
context object いいえ refs ファセットのみ。他のファセットはサーバーがイベントから導出するため、ここでは上書きできない。
curl -X POST "https://<your-instance>/api/v1/agent-events/finalize" \
  -H "Authorization: Bearer spantail_aat_youragenttoken" \
  -H "Content-Type: application/json" \
  -d '{
    "sessionId": "sess_8f21",
    "endedAt": "2026-06-28T09:15:00.000Z",
    "description": "Refactored the auth middleware",
    "context": { "refs": ["github:acme/site#128"] }
  }'

レスポンスは更新後のエージェントセッションで、ingest のレスポンスと同じ形です。

エージェントセッションの一覧

Section titled “エージェントセッションの一覧”

GET /api/v1/agent-entries scope: read

ワークスペース内のエージェントセッションを新しい順で返します。読み取りスコープは呼び出し元の メンバーシップからサーバー側で解決されます。メンバーは自分が所属するプロジェクトのエージェント活動と、 自分のエージェント活動を見られます(未割り当ての活動は所有者のみ)。一方、ワークスペース管理者・ インスタンス管理者はワークスペース内のすべてのエージェント活動を見られます。

クエリパラメータ

名前 必須 説明
workspaceId string はい 一覧対象のワークスペース。
agentId string いいえ 単一エージェントに絞り込み。
from string いいえ 開始日(含む)YYYY-MM-DD
to string いいえ 終了日(含む)YYYY-MM-DD
limit integer いいえ ページサイズ 1〜200(既定 50)。
offset integer いいえ スキップ行数(既定 0)。
curl "https://<your-instance>/api/v1/agent-entries?workspaceId=wrk_demo&agentId=agt_bot" \
  -H "Authorization: Bearer spantail_pat_yourtoken"

POST /api/v1/agent-entries/delete scope: write

自分が所有するエージェントセッションを一括削除します。DELETE ではなくボディ付きの POST です (DELETE のボディは中継で扱いが悪いため)。all-or-nothing で、いずれかの id が存在しない・ 別の所有者のもの・指定ワークスペース外のいずれかであれば、何も削除されず 404403 ではない)を 返します(外部の id の存在を確認させないため)。オーナー専用で、管理者でも他人のセッションは 削除できません。

リクエストボディ

フィールド 必須 説明
workspaceId string はい セッションが属するワークスペース。
ids string[] はい 削除するセッション id(重複は除去されます)。
curl -X POST "https://<your-instance>/api/v1/agent-entries/delete" \
  -H "Authorization: Bearer spantail_pat_yourtoken" \
  -H "Content-Type: application/json" \
  -d '{ "workspaceId": "wrk_demo", "ids": ["ae_01K2", "ae_01K3"] }'

GET /api/v1/agent-entries/stats scope: read

一覧と同じフィルタ集合・同じ ACL で集計した合計を返します。一覧と違い、from/to の日付範囲は 必須 です。これは、行を閲覧者のタイムゾーンで日別にバケットするスキャンを限定します。 ページングはありません。

クエリパラメータ

名前 必須 説明
workspaceId string はい 集計対象のワークスペース。
agentId string いいえ 単一エージェントに絞り込み。
from string はい 開始日(含む)YYYY-MM-DD
to string はい 終了日(含む)YYYY-MM-DD
{
  "totalMinutes": 540,
  "totalTokens": 184000,
  "totalInputTokens": 120000,
  "totalOutputTokens": 64000,
  "entryCount": 12,
  "byDate": [
    { "date": "2026-06-28", "minutes": 42, "tokens": 18400, "count": 1, "inputTokens": 12000, "outputTokens": 6400 }
  ],
  "byAgent": [
    { "agentId": "agt_bot", "minutes": 540, "tokens": 184000, "count": 12 }
  ]
}

トークンバケットを公開しないエージェントは入力/出力の内訳に 0 を寄与するため、その合計は totalTokens より小さくなることがあります。byDate にはエントリのある日付だけが現れます。

ワークスペース内のエージェント一覧

Section titled “ワークスペース内のエージェント一覧”

GET /api/v1/agent-entries/agents scope: read

ワークスペース配下の呼び出し元自身のエージェント(ここで活動があるものと、ここに登録されたもの)を フィルタ用に返します。workspaceId は必須です。

[
  { "id": "agt_bot", "type": "claude_code", "name": "Build bot" }
]