Billing ページで月額の上限を入れようとして、Workspace の一覧を開いた夜がありました。壁紙アプリの小さなバックエンドも、試作用のスクリプトも、同じ API キー 1 本で動かしていたからです。
上限を置きたい相手は「試作」でした。ところが、いちばん使っているキーは既定の Workspace に属していて、そこには支出上限そのものを設定できません。画面の前で、しばらく手が止まりました。
最初にお伝えしたいのは、上限は「キーに」ではなく「Workspace に」置くものだということです。ここからは、用途ごとに Workspace を分けて月額の天井を作る手順と、分けたあとに「本当にそこへ落ちているか」を確かめる検査を書き残します。
既定の Workspace でできないこと、できること
公式ドキュメントの記述を、手元の運用に関係する範囲で整理します。
| 項目 | 既定の Workspace | 自分で作った Workspace |
|---|---|---|
| 名前の変更・アーカイブ・削除 | できない | できる(アーカイブは取り消せない) |
| 月額の支出上限 | 設定できない | 組織の上限以下で設定できる |
| レート制限の個別設定 | — | Rate limits ページで Workspace を選んで設定 |
| 作成できる人 | — | 組織の管理者のみ |
つまり、既定の Workspace にすべてを載せたままでは、組織全体の上限(階層の月間上限か、組織として自分で決めた上限)しか守りの線がありません。試作が暴走したときに、本番のアプリまで巻き込んで止まる構造です。
天井は、止まってよいものの周りにだけ置く。 分ける理由は、この一文に尽きます。
分け方の叩き台
個人開発の規模なら、3 つで足りると考えています。名前は、画面で見たときに用途が分かるものにします。
| Workspace | 載せるもの | 上限の考え方 |
|---|---|---|
| Prod - アプリ本体 | ユーザーに見える機能のバックエンド | 上限は高め。到達したら止めるより通知を先に |
| Batch - 夜間ジョブ | 翻訳・整形などの定期処理 | 1 回の暴走が許せる額を月額で |
| Dev - 試作 | 手元のスクリプト、検証 | 低めに固定。止まっても困らない |
設定は Console の Workspaces ページで対象の Workspace を選び、開いたパネルの Spend limits から行います。月額の上限に加えて、一定の割合に達したときの通知も置けます。Workspace の上限は組織の上限より高くは設定できません。
分けるときに一つだけ、先に知っておきたい点があります。プロンプトキャッシュは Workspace ごとに分離されます。 同じ長いシステムプロンプトを 3 つの Workspace から送ると、キャッシュは共有されません。Prod と Batch で同じ前置きを使い回している場合は、キャッシュの当たり方が変わる可能性があります。私は、前置きを共有していない組み合わせだけを分けました。
分けたあとに起きる、見えにくい失敗
Workspace を作ってキーを発行しても、古いキーが既定の Workspace に残っていれば、そのキーで送った分は上限のない側に積み上がります。しかも、リクエストは成功するので、気づく手がかりがありません。
そこで、レスポンスの anthropic-workspace-id ヘッダを使って、起動時に一度だけ検査します。このヘッダには、リクエストのキーが解決された Workspace の ID が入ります。
# 「このプロセスは意図した Workspace に落ちているか」を起動時に確かめる
import os
import sys
import anthropic
EXPECTED = os.environ["EXPECTED_WORKSPACE_ID"] # wrkspc_ で始まる ID
client = anthropic.Anthropic() # ANTHROPIC_API_KEY を環境変数から読む
raw = client.messages.with_raw_response.create(
model="claude-haiku-5-5",
max_tokens=16,
messages=[{"role": "user", "content": "ping"}],
)
actual = raw.headers.get("anthropic-workspace-id")
if actual != EXPECTED:
print(f"Workspace が違います: expected={EXPECTED} actual={actual}")
sys.exit(1)
print(f"OK: {actual}")何を解決するかといえば、「キーを差し替えたつもりで、実は別の場所に積んでいた」という事故です。期待値は環境変数に置き、デプロイ時の確認手順に 1 行足しておきます。ヘッダが空のときは、認証の前に失敗したか、Admin API のように Workspace に解決されない呼び出しだった可能性があります。
ID の調べ方は 2 通りあります。Console の Workspaces ページに表示されるものを使うか、管理者用のキーで List Workspaces を呼びます。既定の Workspace を一覧に含めたいときは include_default=true を付けます。
上限に当たったときの表示
自分で置いた Workspace の上限に達すると、HTTP 400 で invalid_request_error が返ります。メッセージは「You have reached your specified workspace API usage limits」で始まり、再開の時刻が書かれます。
429 ではないため、再試行しても通りません。この切り分けは上限に達したのに 400 が返ってきた — 自分で決めた利用上限・階層の月間上限・レート制限を見分けるに詳しく書きました。ここでは、Workspace の上限は 400 で来る とだけ覚えておけば十分です。
なお、Claude Code 用の Workspace だけは例外的に扱いが異なります。上限の判定が別枠で、retry-after 付きの 429 になる場合があります。Claude Code を同じ組織で使っている方は、頭の片隅に置いてください。
日別に、Workspace ごとの消費を見る
上限を置いたら、次は「どれくらい近いか」を見える状態にします。Usage and Cost Analytics API(ベータ)では、Workspace ID で絞り込み・集計ができます。
# Workspace ごと・日別のトークン消費を取り出す
import os
import anthropic
# 管理者用のキー(Workspace に紐づかないもの)が必要です
client = anthropic.Anthropic(api_key=os.environ["ADMIN_API_KEY"])
rows = client.beta.organization.analytics.usage.list(
starting_at="2026-11-01T00:00:00Z",
ending_at="2026-11-08T00:00:00Z",
time_bucket_width="1d",
group_by=["workspace_id"],
)
for row in rows:
print(f"{row.starting_at} {row.group.workspace_id}: {row.usage.total_tokens}")既定の Workspace の使用量は、その Workspace 自身の ID で出てきます。分けた直後は、既定側の数字が減っていくかを見ると、移行の漏れに気づけます。なお、これはトークン数の集計です。金額で見たいときは、同じ系統の Cost Report 側を確かめていただければと思います。
手順のまとめ
順番は、次のとおりです。
- 用途を洗い出し、止まってよいものから順に Workspace を作ります(管理者権限が必要です)。
- 各 Workspace で Spend limits を設定します。
- Workspace に紐づくキーを発行し、環境変数を差し替えます。
- 起動時の検査で
anthropic-workspace-idを確かめます。 - 数日後、Analytics API で既定の Workspace の消費が減っているかを見ます。
次の一歩
月額の見積もり方そのものはClaude API の月額予算を破綻させない設計 — 個人開発者のための実践コスト管理にまとめています。
まず Console で、いま動いているキーがどの Workspace に属しているかを確かめてみてください。既定の Workspace に載っているなら、いちばん止まってよい用途から一つ切り出すところが始め時だと思います。
私も最初に切り出したのは試作用でした。あの夜に感じた「止められないものを、止められない場所に置いていた」という居心地の悪さは、いまのところ戻ってきていません。