クイックアンサー: Claude Batch APIは、Messages APIのリクエストを非同期で処理し、入力トークンと出力トークンの両方で50%オフの価格を提供します。1回の呼び出しで最大10万件のリクエスト(または256MB)を送信し、バッチが終了するまでポーリングを行い、その後独自のcustom_idでキー付けされた結果を読み取ります。ほとんどのバッチは1時間以内に完了し、硬い上限は24時間です。
分類したいサポートチケットが4万件ある場合でも、プロダクトカタログを書き換えたい場合でも、あるいは1か月のトランスクリプトを要約したい場合でも、どれも急いでいるわけではないかもしれません。これらの呼び出しを1つずつ実行しても、いずれフル価格での請求が発生し、レート制限に違反するリトライを調整する午後の時間を費やすことになります。
Claude Batch APIは、まさにこのような作業のために存在します。Anthropicにリクエストのリストを渡して、離れ、同じ呼び出しを同期的に行っていた場合と比較して半額でコストがかかる結果のファイルに戻ってくるのです。キューを待つ必要も、並行処理のチューニングも、バックオフロジックも不要です。
このガイドでは、バッチエンドポイントが何を行うのか、費用はいくらか、ジョブを送信して取得する方法、そして実際のデータに適用する前にApidog CLIを使ってコーディングエージェントに全てテストさせる方法を解説します。
Claude Batch APIとは?
Claude Batch APIは、/v1/messages/batchesという非同期エンドポイントであり、一度のリクエストで多数のMessages APIリクエストを受け取り、処理が終了した後にその結果を返します。これはレイテンシと引き換えに50%割引を提供します。Anthropicでは、バッチ処理としてこれを文書化しています。
設計する際に考慮すべき制約は以下の通りです:
- サイズ:バッチあたり最大10万リクエストまたは256MB、どちらか先に到達した方が上限となります。
- タイミング:ほとんどのバッチは1時間以内に完了します。処理が完了しないリクエストは24時間で期限切れになります。
- 保持期間:結果はバッチが作成されてから29日間利用可能です。
- 機能の互換性:ビジョン、ツール使用、システムプロンプト、プロンプトキャッシュはすべてバッチ内で動作します。
- 順序:結果は任意の順序で返されるため、位置で指定するのではなく、
custom_idでキー付けを行う必要があります。
この最後の点が多くの人々を悩ませるポイントです。バッチはキューではなく、バッグなのです。
Claude Batch APIの費用
割引は、それぞれのリクエストが指定したモデルに対して、入力トークンと出力トークンの両方で一律50%オフとなります。1つのバッチ内でモデルを混合できるため、安価な分類器と高価な要約器を一緒に使用することが可能です。

| Model | Standard input / output per MTok | Batch input / output per MTok |
|---|---|---|
| Claude Opus 5.5 | $4.00 / $20.00 | $2.00 / $10.00 |
| Claude Sonnet 5.5 | $2.00 / $10.00 | $1.00 / $5.00 |
| Claude Haiku 5.5 (prompts up to 100K) | $0.10 / $0.50 | $0.05 / $0.25 |
| Claude Haiku 5.5 (prompts over 100K) | $0.50 / $2.50 | $0.25 / $1.25 |
Haikuの行をよく読んでください。Haiku 5.5の価格はプロンプトのサイズによって決まるため、100,000トークンを超える単一のプロンプトは、バッチ割引の有無にかかわらず、短文プロンプト料金の5倍を請求します。長文のHaiku作業は、$0.25 / $1.25と見積もってください($0.05 / $0.25ではありません)。これらの数字に基づいて予測を立てる前に、Anthropicの料金ページを確認し、請求額があなたの滞在理由である場合は、Claude APIの使用料がどこに使われるかのブレイクダウンを読んでください。
バッチプライシングは、プロンプトキャッシュと組み合わせることができ、そこが本当の節約ポイントです。詳細は後述します。
最初のバッチを送信する
公式Python SDKをインストールし、リクエストのリストを作成します。各リクエストには、あなたが選んだcustom_idと、通常のmessages.create()呼び出しと全く同じ見た目のparamsオブジェクトが付随します。
import anthropic
from anthropic.types.message_create_params import MessageCreateParamsNonStreaming
from anthropic.types.messages.batch_create_params import Request
client = anthropic.Anthropic()
tickets = [
"Card declined three times, support chat timed out.",
"Love the new dashboard, the export button is hidden though.",
"Webhook stopped firing after the 2.4 upgrade.",
]
batch = client.messages.batches.create(
requests=[
Request(
custom_id=f"ticket-{i}",
params=MessageCreateParamsNonStreaming(
model="claude-haiku-5-5",
max_tokens=1024,
output_config={"effort": "low"},
messages=[{
"role": "user",
"content": f"Label this ticket billing, bug, or praise. One word.\n\n{text}",
}],
),
)
for i, text in enumerate(tickets)
]
)
print(batch.id, batch.processing_status)
custom_idに意味を持たせてください。データベースの主キーやファイルパスにすると、後で結合(join)を行う必要がなく、結果を元の入力に結びつける唯一の手段になります。
生のHTTPを好む場合は、同じペイロードをPOST https://api.anthropic.com/v1/messages/batchesに送信し、x-api-keyとanthropic-versionヘッダーを使用します。メッセージバッチの参照を生成するには、完全なスキーマが確認できます。
バッチをポーリングして結果を収集する
processing_statusがendedを指すまでバッチをリトリーブし、結果をストリーム処理します。各結果には、設定したcustom_idと、succeeded、errored、canceled、またはexpiredのresult.typeが付随します。
import time
while True:
batch = client.messages.batches.retrieve(batch.id)
if batch.processing_status == "ended":
break
print("still working:", batch.request_counts.processing)
time.sleep(30)
labels, retry = {}, []
for result in client.messages.batches.results(batch.id):
if result.result.type == "succeeded":
msg = result.result.message
labels[result.custom_id] = next(b.text for b in msg.content if b.type == "text")
elif result.result.type == "errored":
retry.append(result.custom_id)
print(f"{len(labels)} labeled, {len(retry)} need another pass")
2つの失敗モードは個別に処理されるべきです。invalid_requestエラーはリクエストボディが間違っていることを意味するので、再送信する前に修正が必要です。それ以外のエラーはサーバー側のものであり、そのまま再試行しても安全です。expiredな結果とは、リクエストが実行される前に24時間のウィンドウが閉じたことを意味するので、これらも再送信する必要があります。
ポーリングは30秒から60秒間隔で行ってください。1秒ごとにリトリーブエンドポイントを叩いても得られるものはなく、Claude APIのレート制限に抵触します。
プロンプトキャッシュとバッチプライシングを組み合わせる
最大のメリットは、この2つの割引を組み合わせることで生まれます。バッチ内のすべてのリクエストが長いプレフィックス(接頭辞)、スタイルガイド、タクソノミー、40ページの契約書などを共有している場合、そのプレフィックスにcache_controlを指定し、すべての1万件のリクエストで同じマークされたプレフィックスを送信してください。
shared_system = [
{"type": "text", "text": "You are a support triage analyst."},
{
"type": "text",
"text": taxonomy_document, # 数千のトークン、毎回同一
"cache_control": {"type": "ephemeral"},
},
]
このsystemブロックをバッチ内の各Requestに適用してください。プレフィックスがライブキャッシュエントリのバイト単位で一致するリクエストは、そのプレフィックスをキャッシュ読み取りレートで請求し、50%のバッチ割引がキャッシュの読み取りと書き込みの両方に適用されます。完璧なヒット率を予算に組み込まないでください。バッチはリクエストを順番に処理するのではなく、並行して処理するため、1つのバッチ内でのキャッシュヒットはベストエフォートとなります。Anthropicのプロンプトキャッシュガイドはプレフィックスのルールを網羅しています:ブレークポイントより前に変更されるバイトは、それ以降のすべてを無効にするため、タイムスタンプとキャッシュされたブロック以降の個別のテキストを維持してください。
Apidog CLIでClaude Codeにエンドポイントをテストさせる
10万件もの本番リクエストにお金を費やす前に、バッチライフサイクル(作成、取得、結果)に関する回帰テストを行いたいものです。GUIで手動で行うのは手間がかかります。コーディングエージェントにApidog CLIを使って実行させましょう。
npm install -g apidog-cli@latest
apidog auth login --with-token <YOUR_TOKEN>
apidog skill install # 促されたらClaude Codeを選択
次に、Claude Codeに以下のプロンプトを与えます。
Apidog project 4820193内で、POST https://api.anthropic.com/v1/messages/batchesのエンドポイントのテストケースを作成してください。custom_id ticket-0とticket-1を持つ2つのHaiku 5.5リクエストを送信し、応答にidとprocessing_statusが含まれていることをアサートし、その後GET /v1/messages/batches/{id}をポーリングしてprocessing_statusがendedになるまで待機させます。これをanthropic-staging環境で実行し、失敗を要約してください。
エージェントはペイロードスキーマを読み取り、自身のJSONを検証し、ケースを作成して実行します。
apidog cli-schema get test-case-create
apidog cli-schema validate test-case-create --file batch-case.json
apidog test-case create --project 4820193 --file batch-case.json
apidog run --test-case 77214 --project 4820193 -e 992301 -r cli,json
APIキーはApidogのエンドポイント変数内に保持されるため、プロンプトやリポジトリに保存されることはありません。リポーターを-r junitに変更すれば、この同じコマンドがマージのたびにCIで実行されます。これは、私たちのApidog CLIパイプラインガイドで紹介されているセットアップと同じです。CLIをまだエージェントに接続していない場合は、Claude CodeでApidog CLIを使用することから始めましょう。
バッチが不適切な場合

| Workload | Use batch? | Why |
|---|---|---|
| Nightly summarization of yesterday’s logs | Yes | Nobody is waiting; 50% off |
| Backfilling embeddings or labels over a corpus | Yes | Fits the 100,000-request ceiling |
| Evaluation runs across a prompt suite | Yes | Results keyed by custom_id map to test IDs |
| Chat UI responses | No | Users will not wait an hour |
| An agent loop that needs the last answer to pick the next step | No | Batch requests cannot see each other |
| A request that must beat a 5-second SLA | No | No latency guarantee below 24 hours |
適用できないケースもいくつかあります。Fast modeはBatch APIでは利用できません。サーバー側での拒否フォールバックもサポートされていません。また、Claude Opus 5.5およびClaude Sonnet 5.5では、強制的なtool_choiceがanyまたはtoolの場合、通常の呼び出しと同じようにバッチ内で400エラーを返します。代わりにtool_choice: autoとstrict: trueを使用してください。
マルチプロバイダーのインフラを運用している場合、他の場所でも同じパターンが存在します。OpenAIのOpenAI Batch APIやGemini APIバッチモードを見てください。形状は異なりますが、経済的メリットは変わりません。
FAQ
Claude Batch APIとは何ですか?
標準のMessages APIリクエストを大量に、通常トークン価格の50%で実行する非同期エンドポイントです。独自のIDを付けてリクエストのリストを送信し、バッチが終了するまでポーリングし、29日以内に出力結果を読み取ります。
Claude Batch APIの費用はいくらですか?
入力と出力の両方で標準料金の半分です。Claude Sonnet 5.5の場合、同期での2.00ドルと10.00ドルに対し、バッチでは入力100万トークンあたり1.00ドル、出力100万トークンあたり5.00ドルです。
Claudeのバッチにかかる時間はどのくらいですか?
ほとんどのバッチは1時間以内に完了します。最大は24時間で、それ以降に未処理のリクエストはexpired結果を返し、再送信する必要があります。
バッチ内でプロンプトキャッシュを使用できますか?
はい、そして割引はスタック(積み重ね)されます。共有するプレフィックスをcache_controlでマークし、その同一のプレフィックスをすべてのリクエストに繰り返し送信することで、キャッシュされた読み取りが入力価格の大部分の割引された価格で請求されます。さらにバッチ割引も適用されます。
バッチ内の1つのリクエストが失敗した場合、どうなりますか?
そのリクエストのみが失敗します。結果にはtype: "errored"とエラーオブジェクトが伴いますが、それ以外のすべては成功しています。バリデーションエラーには修正されたペイロードが必要ですが、サーバーエラーは変更せずに再試行しても安全です。
実行中のバッチをキャンセルできますか?
はい。client.messages.batches.cancel(batch_id)を実行すると、バッチはcanceling状態になります。すでに完了したリクエストの結果は維持されますが、残りはcanceledとして返されます。
Batch APIはツールと画像をサポートしていますか?
はい。ビジョン、ツールの定義、システムプロンプトを含むMessages APIのすべての機能がバッチ内で動作します。例外はFast mode、サーバー側でのフォールバック、および5.5モデルでの強制的なツール選択です。
まとめ
バッチ処理は、プロンプトキャッシュに次いでClaude APIにおける最大の無料節約方法であり、品質の面で何も犠牲になりません。同じモデル、同じ機能、半額の価格であり、それはあなたが利用していなかったレイテンシによって支払われています。結果をcustom_idでキー付けし、共有プレフィックスをキャッシュし、expiredを失敗ではなく再試行として扱うことが重要です。
スケールさせる前にライフサイクルをテストしてください。Apidog CLIをインストールし、コーディングエージェントをバッチエンドポイントに向けることで、スキーマの変更が10万件のリクエストで予期せぬ事態を引き起こすのを防ぎます。無料プランは4ユーザーをカバーしており、Apidogをダウンロードして数分で最初のテストを実行できます。
