Analytics APIのusersでメンバー別・グループ別の活動を取る
Claude Enterprise Analytics APIの/usersで、メンバー別の日次活動をカーソルで全件取得し、group_byでRBACグループ集計、filterでユーザー・グループ・プロジェクトに絞る方法。
Claude Enterprise Analytics APIのGET /v1/organizations/analytics/usersは、組織のメンバーごとに1日分の活動指標を返すエンドポイントです。行はメールアドレス順に並び、group_by[]=rbac_group_idを付けるとRBACグループ単位の集計に、filter[]を付けると特定のメンバー・グループ・チャットプロジェクトに絞れます。Claude Enterpriseプランの組織で、read:analyticsスコープのAPIキーが要ります。
このエンドポイントの手前にある概観はコネクタ・スキル・プラグインのAnalytics API解説にあります。ここでは/usersだけに絞り、ページ送りのループ、group_byで行がどう変わるか、filterの組み合わせ制約、応答のどこがnullになるかを順に見ます。
キーの用意
Analytics APIのキーを作れるのは、組織のプライマリーオーナーだけです。プライマリーオーナーでサインインし、claude.aiの組織設定の「API」でAPIアクセスを有効にしてから、Analytics APIキーを作ります。キーにはread:analyticsスコープが付き、画面に表示されたシークレットはその場で控えて、シークレット管理の仕組みに保管します。
最小のリクエストと、返ってくる行の形
1日分を取るにはdateにUTCの日付を渡します。データは通常1日遅れで出るため、昨日の日付が基本です。公開の目安は翌日のUTC 13:00〜13:30ごろで、それまでは最新の取得可能日がUTC日付の2日前になります。日本時間の朝に「昨日」を渡すと、まだ出ていない日付になることがあるので、UTCの日付で数えてください。早すぎる日付を渡すと400が返り、エラーが最新の取得可能日を教えてくれます。
curl -G https://api.anthropic.com/v1/organizations/analytics/users \
-H "anthropic-version: 2023-06-01" \
-H "X-Api-Key: $ANTHROPIC_ANALYTICS_KEY" \
--data-urlencode "date=2026-10-18" \
--data-urlencode "limit=1000"limitは1〜1000で、既定は100です。応答はdata(行の配列)とnext_page(次ページのカーソル、無ければnull)の2つで構成されます。個人の行にはuserオブジェクトが付き、中身はid(user_...形式)とemail_addressです。
1行は製品別のブロックに分かれています。
| ブロック | 中身 |
|---|---|
chat_metrics | 中身claude.aiチャットのメッセージ数、会話数、コネクタ・スキル利用、アーティファクト作成など |
claude_code_metrics | 中身core_metrics(コミット数、PR数、セッション数、追加・削除行数)とtool_actions(編集系ツールの承認・拒否数) |
cowork_metrics | 中身メッセージ数、ツールアクション数、スキル・コネクタ・プラグイン利用、Dispatchのターン数 |
design_metrics | 中身Claude Designのプロジェクト作成数・利用数、セッション数、メッセージ数 |
office_metrics | 中身excel / outlook / powerpoint / wordごとのメッセージ数、セッション数、スキル・コネクタ利用 |
science_metrics | 中身Claude Scienceのメッセージ数、セッション数、委任数、リモート計算ジョブ数 |
web_search_count | 中身ウェブ検索の回数(ブロックではなく単独の数値) |
tool_actionsにはedit_tool・multi_edit_tool・notebook_edit_tool・write_toolがあり、それぞれaccepted_countとrejected_countを持ちます。Claude Codeの提案がどれだけ受け入れられたかは、ここから出せます。
チャットとCoworkを統合している組織では、行にchat_cowork_unified_metricsも付き、chatとsessionsに分かれます。統合中の活動がこちらに移る仕組みはchat_cowork_unifiedの解説にまとめてあります。この項目は、統合を提供していない環境では応答から省かれます。
カーソルで全メンバーを取り切るループ
メンバーが100人を超えるなら、1回の応答では収まりません。next_pageの値を、次のリクエストのpageにそのまま渡します。カーソルは不透明な文字列なので、中身を解釈したり組み立てたりしません。
page=""
while :; do
resp=$(curl -sG https://api.anthropic.com/v1/organizations/analytics/users \
-H "anthropic-version: 2023-06-01" \
-H "X-Api-Key: $ANTHROPIC_ANALYTICS_KEY" \
--data-urlencode "date=2026-10-18" \
--data-urlencode "limit=1000" \
${page:+--data-urlencode "page=$page"})
echo "$resp" | jq -c '.data[]' >> users-2026-10-18.jsonl
page=$(echo "$resp" | jq -r '.next_page // empty')
[ -z "$page" ] && break
sleep 2
doneループの終了条件はnext_pageがnullになることだけです。「返ってきた行数がlimit未満」で打ち切る書き方は避け、必ずnullを見てください。
レート制限にも注意が要ります。上限は組織単位で、既定は全エンドポイント合わせて毎分60リクエストです。キーを増やしても上限は増えず、このAPIの他のエンドポイントと枠を共有します。ループの途中で別の集計ジョブが走っていると、思ったより早く枠を使い切ります。例のsleep 2は枠を使い切らないための間隔で、429が返ったときは待ってから同じpageでやり直します。上限が足りないときは、Anthropicのアカウント担当に相談する扱いです。
2回目以降のリクエストでは、dateやgroup_by[]、filter[]は1回目と同じ値を渡し続けます。期間指定のときは、省略したending_date(既定は今日)が最初のページを返した時点で一度だけ決まり、残りのページでも使い回されます。ページ送りの途中で日付をまたいでも、範囲は変わりません。
出力を1行1JSONのファイルに溜めておくと、あとからjqやDWHへの取り込みで同じデータを何度でも読めます。
group_by[]=rbac_group_idで行がどう変わるか
group_by[]が受け付ける値はrbac_group_idだけです。メンバーごとの行をやめて、RBACグループごとの集計行にします。ほかの次元を渡すと400になります。
curl -sG https://api.anthropic.com/v1/organizations/analytics/users \
-H "anthropic-version: 2023-06-01" \
-H "X-Api-Key: $ANTHROPIC_ANALYTICS_KEY" \
--data-urlencode "date=2026-10-18" \
--data-urlencode "group_by[]=rbac_group_id" \
| jq -r '.data[] | [.rbac_group_name, .distinct_user_count,
.chat_metrics.message_count] | @tsv'グループ行では、個人の行と次の点が変わります。
userはnullです。集計行なので特定のユーザーを指しませんrbac_group_id(rbac_group_...形式)が付きます。支出上限APIの表記と同じですrbac_group_nameが付きます。グループが削除されていたり名前を解決できなかったりするとnullで、安定したキーはrbac_group_idのほうですdistinct_user_countが付きます。そのグループで活動したメンバーの人数で、グループ集計のときだけ設定されます
グループ行は排他的な分割ではありません。1人のユーザーは、その日に所属していたすべてのグループの行に計上されます。2つのグループに入っている人の活動は、両方の行に入ります。グループ別の行を足し合わせると、組織全体の値を超えることがあります。部門ごとの利用量を比べるときは問題ありませんが、「部門の合計=全社」という検算は成立しません。全社の値が要るなら、group_by[]なしの個人行を足し合わせるほうが安全です。
グループIDの調べ方はCompliance APIで組織データを取る手順で扱っています。グループの支出上限と見比べたいときはグループ支出上限の設定が対になります。
filter[]で絞れる3つの次元
filter[]はdimension:valueの形で、/usersで使える次元は3つです。同じ次元を繰り返すとOR、別の次元を並べるとANDになります。最大100件、未対応の次元は400です。
| 次元 | 値の形 | 備考 |
|---|---|---|
user_id | 値の形user_... | 備考応答のuser.idと同じ形式。メールアドレスではない |
rbac_group_id | 値の形rbac_group_...、または素のグループUUID | 備考対象の各UTC日にそのグループに所属していたユーザーに一致する |
project_id | 値の形claude_proj_... | 備考各メンバーの行を、そのプロジェクト内のclaude.aiチャット活動に限る |
組み合わせの例を挙げます。--data-urlencodeの引数だけを示します。
# 2つのグループのどちらかに所属するメンバー(OR)
--data-urlencode "filter[]=rbac_group_id:rbac_group_AAAA" \
--data-urlencode "filter[]=rbac_group_id:rbac_group_BBBB"
# そのグループに所属し、かつ指定ユーザーである行(AND)
--data-urlencode "filter[]=rbac_group_id:rbac_group_AAAA" \
--data-urlencode "filter[]=user_id:user_XXXX"IDは説明用の仮の値です。実際の値は応答のuser.idやrbac_group_id、Compliance APIの出力から取ります。
project_idだけは扱いが違う
project_idのフィルターには、ほかにない制約があります。
group_by[]と併用できませんrbac_group_idのフィルターとも併用できません- 行の対象はclaude.aiのチャット活動だけになります。Claude CodeやCoworkの値は、プロジェクト単位では出ません
chat_cowork_unified_metrics.sessionsの件数はすべて0になります。セッションはプロジェクト単位で計測されないためです- チャットとCoworkの統合が有効な日にメッセージを送ったメンバーは、その日のプロジェクト活動がすべて
chat_cowork_unified_metrics.chat側に入り、chat_metricsには入りません
プロジェクト別の利用量を見るときは、chat_metricsだけを読むと統合済みのメンバーの分が抜けます。両方のブロックを足してください。
落とし穴
プロジェクト別集計で統合済みメンバーの分が消える
project_idで絞った行のchat_metrics.message_countだけを集計すると、Chat and Cowork unifiedを使っている日のメッセージが0に見えます。同じ日の活動はchat_cowork_unified_metrics.chat.message_countに入っているため、2つを足した値で比べます。
日次ではなく期間で取る
dateの代わりにstarting_date(含む)とending_date(含まない)を渡すと、メンバーごとに期間全体を1行へ畳むロールアップモードになります。dateとstarting_dateは併用できず、範囲は最大366日、日付は2026-01-01以降です。
足し算できる件数は日ごとの値の合算です。人数やセッション数のように二重に数えかねない値は、期間全体で数え直されます。近似になるものはHLLで、典型誤差は2%未満です。行を畳んで数えられない項目はnullで返ります。
読み取りで押さえる点は次のとおりです。
- 多くの
distinct_*_countはnumber or nullで、期間モードでは近似値かnullになる distinct_artifacts_created_countとdistinct_projects_created_countは、作成が必ず1日に属すので、期間でも正確な値になるlast_activity_dateは、期間内で何らかの活動があった最新のUTC日を返すdistinct_session_count(Claude Code)は日ごとの合計で、1つのセッションがUTC日をまたぐことはほぼないため、実質的に正しい数になる
order_byとorderでランキングも作れます。指標をorder_byに指定すると既定は降順で、上位N件の取得に向きます。指定できるのはエンドポイントの並び替え列とランキング可能な指標に限られ、一部の指標は期間モードでしか使えません。使える名前の一覧は、このエンドポイントのリファレンスで確かめます。
実装前に確認しておく点
- 直近は改訂される: 値は取得後の数日で数%動くことがあります。確定値が要る月次レポートは、数日置いてから取ります
- Bedrock経由のClaude Codeは返らない: Claude CodeをAmazon Bedrock経由で使っている分の活動は、このAPIに出ません。Bedrockで使うメンバーの
claude_code_metricsが0でも、使っていないとは限りません - 0とnullは違う: 機能が有効でない組織では、一部のCowork項目(プラグイン利用やファイル編集の件数)がnullです。「使われていない」とは別の意味です
- 未使用の製品はゼロ埋め: 製品ブロックが欠けることはなく、使っていないメンバーは0が並びます。活動の有無は
last_activity_dateでも見られます - メールを主キーにしない: 行を突き合わせるキーは
user.idです。ID列を保存しておくと、メールアドレスの変更に影響されません - ボリュームを見積もる: 全メンバーを毎日取ると、組織の人数ぶんの行が日ごとに増えます。日次で貯めるなら、1行1JSONで追記しておくと扱いやすくなります
Claude Codeに取得スクリプトを書かせるとき
ここまでの制約を、そのままプロンプトの条件にできます。例えば次のように伝えます。
/v1/organizations/analytics/users を日次で取得して JSONL に追記するスクリプトを書いて。
- date は UTC の昨日
- next_page が null になるまで page で追う。行数での打ち切りはしない
- 行の突き合わせキーは user.id
- project_id フィルターは group_by と併用しない
- 取得後に jq で wc -l を取り、メンバー数と大きく違えば警告する書かせたあとは、実際に1日分を実行して行数とnext_pageの最終値を確認します。生成されたコードが期待どおりかは、手元の出力で判断します。
ユーザー別のコストは別のエンドポイントで、ユーザー別コストの取得が受け持ちます。/usersが返すのは利用の回数・件数であり、金額ではありません。どのAnalytics APIから始めるかはClaude Analytics API群の使い分けが早見表になっています。
まとめ
/usersは、日次のメンバー別行が基本で、group_by[]=rbac_group_idで部門集計、filter[]でユーザー・グループ・プロジェクトへの絞り込みになります。ループはnext_pageがnullになるまで、グループ行は重複計上を前提に読み、project_idだけは単独で使う。この3点を守れば、行数や合計のズレで迷うことはほぼなくなります。