Claude Code Routineをfire APIで外部から起動する手順
Routineの/fireエンドポイントを使い、CIの失敗やアラートからClaude Codeのセッションを起動する手順。ヘッダ、textの扱い、429とリトライの設計までを扱います。
Claude Codeの/fireエンドポイントは、保存済みのRoutineをHTTPのPOST一発で起動する入口です。CIの失敗やアラート検知をきっかけに、Claude Codeのセッションをクラウド上で立ち上げられます。リクエストが返るのはセッション作成の時点で、実行の完了やストリーム出力は待ちません。レスポンスに入っているセッションURLを開いて、進行を追う形になります。
このAPIは実験的な位置づけで、リクエストとレスポンスの形、レート制限、トークンの意味が変わる可能性があると明記されています。Routine全体の仕組みはClaude Code Routines完全ガイドにあり、ここでは/fireを外部から叩く部分だけを掘り下げます。
通常のAPIと何が違うか
/fireはClaude Platformの一部ではなく、Claude Codeの製品面に属します。Claude APIの感覚で扱うと、認証で最初につまずきます。
| 観点 | /fire | Claude Platform API |
|---|---|---|
| 認証 | /fireAuthorization: Bearer(Routine単位のトークン) | Claude Platform APIx-api-key(Consoleで発行) |
| トークンの範囲 | /fire1つのRoutineのみ。読み取り権限なし | Claude Platform APIワークスペース単位 |
| SDK | /fireなし | Claude Platform API各クライアントSDKで利用可 |
| 課金 | /fireclaude.aiのClaude Codeサブスクリプション枠 | Claude Platform APIPlatformの利用量 |
| パス | /fire/v1/claude_code/... | Claude Platform API/v1/... |
呼び出せるのは、Claude Code on the webが有効なPro・Max・Team・Enterpriseのclaude.aiアカウントです。ANTHROPIC_BASE_URLで向き先を切り替える類の設定とは無関係で、APIキーをトークンの代わりに渡しても通りません。
スケジュールやGitHubトリガーとの使い分け
Routineのトリガーは3種類で、1つのRoutineに組み合わせられます。たとえばPRレビュー用のRoutineを、毎晩の定期実行、デプロイスクリプトからの呼び出し、新しいPRへの反応の3つで動かせます。
| トリガー | 起動のきっかけ | 向く場面 | 上限 |
|---|---|---|---|
| スケジュール | 起動のきっかけ毎時・毎晩・毎週などの周期、または1回だけの日時指定 | 向く場面バックログの整理、ドキュメントのずれの点検 | 上限アカウントで1時間に100回。超えた実行は待たされる |
| GitHub | 起動のきっかけPRやリリースなどのリポジトリイベント | 向く場面PRごとのレビュー、マージ後の他言語SDKへの反映 | 上限Routine単位とアカウント単位の1時間あたり上限。超えたイベントは破棄される |
API(/fire) | 起動のきっかけ外部からのHTTP POST | 向く場面アラート、デプロイ後の検証、社内ツールからの呼び出し | 上限Routineで30回、アカウントで100回(1時間あたり) |
イベントがGitHub上で完結するならGitHubトリガー、時刻で決まるならスケジュール、GitHub以外のシステムが発火源ならAPIトリガーという分け方になります。上限の性質も違います。スケジュールは超えると待たされますが、GitHubとAPIは超えた分が実行されません。アラートのように取りこぼしが困る入口にAPIを使うなら、上限を見込んだ設計が要ります。
準備: URLとトークンを手に入れる
トークンはWebのUIでしか作れません。CLIからはトークンの作成・再生成・削除ができません。
API triggerの追加手順
- 1
Routineを編集画面で開く
claude.ai/code/routinesで対象のRoutineを開き、名前の横のメニューから編集を選びます。
- 2
API triggerを足す
「Select a trigger」の欄で「Add another trigger」を押し、APIを選びます。
- 3
URLとトークンを控える
モーダルにURLが出ます。「Generate token」でトークンを作り、その場でコピーします。トークンは一度しか表示されません。
新しいトークンを作ると、前のトークンは失効します。ローテーションは「Regenerate」、API経由の起動を止めたいときは「Delete token」です。IDはroutine_ではなくtrig_で始まります。パラメータ名はroutine_idのままなので、読み違えやすい点です。
最小の呼び出し
URLとトークンをシークレットとして保存し、環境変数経由で渡します。
curl -X POST "$ROUTINE_FIRE_URL" \
-H "Authorization: Bearer $ROUTINE_FIRE_TOKEN" \
-H "anthropic-version: 2023-06-01" \
-H "Content-Type: application/json" \
-d '{"text": "Sentry alert SEN-4521 fired in prod."}'成功すると200 OKで、次の3フィールドが返ります。
{
"type": "routine_fire",
"claude_code_session_id": "session_01HJKLMNOPQRSTUVWXYZ",
"claude_code_session_url": "https://claude.ai/code/session_01HJKLMNOPQRSTUVWXYZ"
}typeは常にroutine_fireです。claude_code_session_urlをSlack通知などに載せておくと、起動したセッションにすぐ飛べます。
anthropic-betaヘッダは必要か
公式の2つのページで、ヘッダの扱いが食い違っています。Claude Code側のdocsのcurl例にはanthropic-beta: experimental-cc-routine-2026-04-01が入っています。一方、Platform側のAPIリファレンスの必須ヘッダはAuthorizationとanthropic-versionの2つで、betaヘッダを送る古い連携も「付けても付けなくても受け付ける」と書かれています。
anthropic-versionは2023-06-01だけが有効値で、欠けたり別の値だったりすると400になります。新規に組むなら、Platform側の記述どおり2つのヘッダで始め、400が出たらベータヘッダの有無を疑う、という順が無難です。
textに何を入れるか
リクエストボディは任意で、フィールドはtextだけです。未知のフィールドは無視されます。
- 中身は自由形式の文字列で、パースされません。JSONを送っても、Routineには文字列そのものが届きます
- 上限は65,536文字で、超えると400になります
- 保存済みのプロンプトに添える形で渡されます
アラート本文、失敗したログの数行、gitのdiffといった、その回だけの文脈に向く欄です。長いログを丸ごと入れるより、末尾の数十行に絞るほうが、上限にも読み取り負荷にも余裕が出ます。
プロンプトが参照しないと無視される
textは裸のメッセージとしては届きません。<routine-fire-payload>ブロックで包まれ、「信頼できないデータ」として扱われます。保存済みプロンプトが明示的に参照しない限り、Claudeはその中の指示に従いません。
つまりRoutine側のプロンプトに、payloadを参照する一文が要ります。
プロンプトでpayloadを参照する
参照がない
CIの失敗を調べて、原因の仮説と修正案をPRの下書きにまとめてください。
参照がある
routine-fire-payloadブロックに書かれたCI失敗の内容を調べ、原因の仮説と修正案をPRの下書きにまとめてください。
左のように書くと、/fireで送ったtextは手がかりとして扱われるだけで、調べる対象にはなりません。右のように「ブロックに書かれた内容」を名指しすると、textが作業の入力になります。
これを書き忘れると、リクエストは200で成功してもセッションはtextを使わずに終わります。トークンが漏れても、textだけで任意の指示を実行させられない設計です。
GitHub Actionsから失敗時に起動する
公式の例は、if: failure()でCIが落ちたときだけ/fireを叩くステップです。
- if: failure()
env:
ROUTINE_FIRE_URL: ${{ secrets.ROUTINE_FIRE_URL }}
ROUTINE_FIRE_TOKEN: ${{ secrets.ROUTINE_FIRE_TOKEN }}
run: |
curl -X POST "$ROUTINE_FIRE_URL" \
-H "Authorization: Bearer $ROUTINE_FIRE_TOKEN" \
-H "anthropic-version: 2023-06-01" \
-H "Content-Type: application/json" \
-d "{\"text\": \"CI failed: $GITHUB_WORKFLOW run $GITHUB_RUN_ID on $GITHUB_REF\"}"URLとトークンの両方をsecretsに置いている点が要です。この例は失敗の事実と実行IDしか渡していません。Routine側にリポジトリが紐づいていれば、プロンプトで「ログはCIの該当runを見て確認する」と指示する構成にできます。ワークフローのYAMLをClaude Codeと一緒に組む手順はGitHub Actionsのワークフロー作成にあります。そちらがCIの中でClaudeを動かす方式なのに対し、Routineは保存済みの設定で毎回同じ状態から起き上がり、CIは起動の合図を送るだけです。
次の形は、公式の例を元にした組み立て例です。ログの末尾をjqでJSONに安全に埋め込み、引用符やバックスラッシュで壊れないようにします。
run: |
tail -n 80 build.log | head -c 60000 > tail.txt
jq -n --rawfile log tail.txt \
--arg run "$GITHUB_RUN_ID" \
'{text: ("CI failed. run=" + $run + "\n" + $log)}' \
| curl -X POST "$ROUTINE_FIRE_URL" \
-H "Authorization: Bearer $ROUTINE_FIRE_TOKEN" \
-H "anthropic-version: 2023-06-01" \
-H "Content-Type: application/json" \
-d @-head -c 60000はバイト数での切り詰めです。日本語などのマルチバイトは1文字が複数バイトになるため、文字数としては上限65,536を下回ります。
429とリトライを設計する
起動回数には時間あたりの上限があります。
API fireの上限(1時間あたり)
1つのRoutine
30回
Run nowと一回限りの再実行を含む合算
アカウント全体
100回
全Routineの合計
上限に達すると429 rate_limit_errorが返り、Retry-Afterヘッダにウィンドウが戻る目安が入ります。失敗が連続して出るCIや、ノイズの多いアラートをそのまま/fireに流すと、数十分で枠を使い切ります。Routine側のRun nowも同じ30回を食うため、手動で試した分も数えます。
エラーごとの原因は次のとおりです。
| ステータス | 原因 | 対処の方向 |
|---|---|---|
| 400 | 原因anthropic-versionの欠落・不正、textが65,536文字超、Routineが一時停止中 | 対処の方向ヘッダと長さを確認し、Routineの有効状態を見る |
| 401 | 原因トークン未指定、またはこのRoutineのものではない | 対処の方向トークンとURLの組を取り違えていないか確認 |
| 403 | 原因アカウントか組織にこのエンドポイントの権限がない | 対処の方向プランと組織の設定を確認 |
| 404 | 原因Routineが存在しない | 対処の方向trig_のIDを確認 |
| 429 | 原因Routineまたはアカウントの時間あたり上限 | 対処の方向Retry-Afterまで待つ |
| 500 | 原因予期しないサーバーエラー | 対処の方向指数バックオフで再試行。続くならリクエストIDを添えて問い合わせ |
| 503 | 原因一時的な過負荷 | 対処の方向少し待って再試行 |
503はClaude Platformの529に相当しますが、このエンドポイントでは503で返ります。
再試行で二重起動する点に注意
冪等キーの仕組みはありません。リトライすると、そのたびに別のセッションが作られます。成功したのにレスポンスだけ受け取れなかった場合も、再送すれば二重起動です。
次は、429のときだけRetry-Afterを待つ最小の例です。5xxの自動再試行は、二重起動を許容できるアラート用途に限るのが安全です。
for i in 1 2 3; do
code=$(curl -s -o resp.json -D hdr.txt -w '%{http_code}' \
-X POST "$ROUTINE_FIRE_URL" \
-H "Authorization: Bearer $ROUTINE_FIRE_TOKEN" \
-H "anthropic-version: 2023-06-01" \
-H "Content-Type: application/json" \
-d '{"text": "deploy check"}')
[ "$code" != "429" ] && break
sleep "$(awk 'tolower($1)=="retry-after:"{print $2+0}' hdr.txt)"
done
echo "status=$code"待ち時間が長くなる場合は、ループで粘るより通知を捨てるか、ジョブを後ろにずらす設計のほうが、CIの実行時間を食いません。
起動できないときの切り分け順
エラー表の原因が複数あるものは、確認の順番を決めておくと早く片づきます。
/fireが失敗したときの確認順
- 1
401ならURLとトークンの組を見る
トークンはRoutineごとに別物です。複数のRoutineを運用していると、別のRoutineのトークンを貼ってしまいがちです。「Regenerate」を押すと前のトークンは失効するので、シークレットを更新し忘れた場合も401になります。
- 2
400ならヘッダ、長さ、Routineの状態の順に見る
anthropic-versionと65,536文字は手元のリクエストで確かめられます。それで直らないときは、詳細ページのオン・オフのスイッチを確認します。一時停止中のRoutineには、/fireも400で弾かれます。 - 3
429なら手動の試行も数える
Run nowもAPI fireも、Routine単位の30回を共有します。動作確認で何度も押したあとに本番のアラートが来ると、枠が残っていないことがあります。
落とし穴
200が返っても、タスクの成功とは限らない
実行一覧の緑の表示は、セッションが開始してインフラのエラーなく終わったことを示すだけです。プロンプトの課題が達成されたかどうかは表れません。ブロックされたネットワークリクエストや、使えないコネクタのツールは、セッションの記録の中に現れます。claude_code_session_urlを開いて、実際に何をしたかを読んでください。
落とし穴
Routineはあなた個人のアカウントに属する
Routineはチームに共有されず、実行はあなたのアカウントの利用枠を使います。Routineがあなたの連携済みのGitHubアカウントやコネクタ経由で行った操作は、コミットもPRもSlack投稿もあなたの名義になります。CIから共有の入口として使うなら、この点を先に決めておくと後で困りません。また、TeamやEnterpriseの管理者はRoutines全体を無効にでき、無効にすると既存のRoutineも止まります。
運用のチェックポイント
- 通知の全件を流さず、落ちたジョブだけ・本番の重大度だけに絞ってから
/fireを呼ぶ - Routine側のプロンプトでpayloadブロックを必ず参照させる
- トークンはシークレットストアに置き、流出や退職時は「Regenerate」で即失効させる
- 同時に複数セッションが立ち上がっても困らないよう、PR作成先のブランチ運用を決めておく。環境やネットワークの制約はクラウド環境の内部構造で整理しています
トークンの権限は、そのRoutineを起動することに限られます。読み取りはできず、他のRoutineやアカウントのデータにも触れません。漏れた場合の影響は、そのRoutineが余分に走る範囲に収まります。