Claude APIのrequest-idをサポート問い合わせで使う方法
Claude APIの全レスポンスに付くrequest-idの取り出し方をSDK別に示し、500エラーでの使いどころとClaude Platform on AWSで2つのIDが返る事情を解説します。
Claude APIのレスポンスには必ずrequest-idヘッダーが付きます。req_018EeWyXxfu5pfWkrYcMdjWGのような値で、エラーレスポンスのJSON本体にもrequest_idフィールドとして同じ値が入ります。サポートへ問い合わせるときはこのIDを添えます。取り出し方は言語ごとに3系統に分かれ、Claude Platform on AWSでは2つのIDが返ります。
request-idはどこに入っているか
request-idは全リクエストのレスポンスヘッダーに付きます。成功でも失敗でも値は入り、エラー時はボディにもrequest_idとして複製されます。
{
"type": "error",
"error": {
"type": "not_found_error",
"message": "The requested resource could not be found."
},
"request_id": "req_011CSHoEeqs5C35K2UUqR7Fy"
}エラーならボディのJSONを見るだけで取れます。成功レスポンスからはヘッダーを読む必要があります。SDKの例外がrequest_idを属性として持っていれば、catchブロックの例外からそのままIDを読めます。言語別の例外クラスはClaude APIのエラー形式とSDK例外クラスの言語別対応表にまとめています。
curlならヘッダーだけを標準出力に出します。-D -でヘッダーを出し、-o /dev/nullで本体を捨てます。
curl -sS -D - -o /dev/null https://api.anthropic.com/v1/messages \
-H "x-api-key: $ANTHROPIC_API_KEY" \
-H "anthropic-version: 2023-06-01" \
-H "content-type: application/json" \
-d '{
"model": "claude-sonnet-5",
"max_tokens": 1024,
"messages": [{"role": "user", "content": "Hello, Claude"}]
}'CLIのantコマンドなら、ant --debug messages create ...のように--debugを付けると標準エラー出力にrequest-idが出ます。一方、antの出力形式はレスポンス本体を出すもので、ヘッダーは出ません。AWS側のIDまで見たいときはcurlの-iかSDKを使います。
言語ごとの取り出し口は3系統ある
Python・TypeScriptだけが、レスポンスオブジェクトのプロパティを読む形です。それ以外の言語は、ヘッダーを読む経路が一段深くなります。
request-idの取り出し口
プロパティ(Python・TypeScript)
message._request_idで読めます。レスポンスオブジェクトのプロパティなので、ヘッダーを意識する必要はありません。raw response(C#・Go・Java・PHP)
C#は
response.RequestID、Javaはresponse.requestId().orElse(null)で読みます。Goはoption.WithResponseInto(&response)でHTTPレスポンスを受け、response.Header.Get("request-id")で読みます。PHPは->rawで受けてgetHeaderLine('request-id')です。ミドルウェア(Ruby)
request_optionsにミドルウェアを渡し、SDKがパースする前のレスポンスからヘッダーを読みます。response.headersのキーは小文字です。
PythonとTypeScriptの最小例です。
message = client.messages.create(
model="claude-sonnet-5",
max_tokens=1024,
messages=[{"role": "user", "content": "Hello, Claude"}],
)
print(f"Request ID: {message._request_id}")const message = await client.messages.create({
model: "claude-sonnet-5",
max_tokens: 1024,
messages: [{ role: "user", content: "Hello, Claude" }]
});
console.log("Request ID:", message._request_id);Rubyはプロパティ読み取りの感覚で書けないので、ミドルウェアのラムダを渡します。
request_id = nil
read_request_id = lambda do |request, call_next|
response = call_next.call(request)
request_id = response.headers["request-id"]
response
end
client.messages.create(
model: Anthropic::Model::CLAUDE_SONNET_5,
max_tokens: 1024,
messages: [{ role: "user", content: "Hello, Claude" }],
request_options: { middleware: [read_request_id] }
)
puts "Request ID: #{request_id}"request-id以外のヘッダーを読むときも同じ経路です。ラッパーの名前だけ言語ごとに違い、Pythonはwith_raw_response、TypeScriptは.withResponse()、Javaは.withRawResponse()、C#はWithRawResponseを使います。
500エラーが続くときの手順
ステータスごとの対処はエラーページに書かれています。その中でサポート連絡が出てくるのは500だけです。500はapi_errorで、Anthropic側のシステム内部で起きた想定外のエラーを指します。手元のリクエストを直しても解消しないため、指数バックオフで再試行し、続くときにサポートの出番になります。
500 api_errorが返ったとき
- 1
SDKの自動再試行に任せる
公式SDKは接続エラー・レート制限・5xxを指数バックオフで、既定で2回再試行します。
retry-afterヘッダーがあればそれに従います。回数はmax_retries(TypeScript・Java・PHPはmaxRetries)で変えられます。 - 2
それでも続くならIDを控える
再試行を尽くした後のレスポンスからrequest-idを取り出します。
- 3
サポートへ連絡する
request-idを添えて連絡します。発生時刻とモデル名も控えておくと、状況を説明しやすくなります。
ほかのステータスの対処は次のとおりです。
| ステータス | エラー種別 | エラーページの対処 |
|---|---|---|
| 400 | エラー種別invalid_request_error | エラーページの対処リクエストの形式・内容を直す。組織・ワークスペースの支出上限に達した場合も400 |
| 401 | エラー種別authentication_error | エラーページの対処APIキーの不備(形式・失効・期限切れ)。Claude Platform on AWSではAWS資格情報やSigV4署名の問題も指す |
| 402 | エラー種別billing_error | エラーページの対処支払い情報を確認する(AWS Marketplace経由ならAWS Marketplaceで確認) |
| 403 | エラー種別permission_error | エラーページの対処組織のアクセスとワークスペース設定を見直す |
| 404 | エラー種別not_found_error | エラーページの対処エンドポイントのパスとリソースIDを見直す |
| 409 | エラー種別conflict_error | エラーページの対処競合を解消してから再試行する |
| 413 | エラー種別request_too_large | エラーページの対処リクエストサイズを減らす。Messages APIの上限は32MB |
| 429 | エラー種別rate_limit_error | エラーページの対処レート制限、またはティアの月間支出上限への到達 |
| 504 | エラー種別timeout_error | エラーページの対処長い処理はストリーミングで受ける |
| 529 | エラー種別overloaded_error | エラーページの対処全ユーザー合計のトラフィックが高いときのAPI過負荷 |
429のうち、ティアの月間支出上限が原因のものはretry-afterヘッダーが付かず、アクセスが再開するまで失敗し続けます。Claude Codeワークスペースの支出上限は、400ではなく429で返ることがあります。
504には別の事情もあります。非ストリーミングで大きなmax_tokensを指定すると、アイドル接続を切るネットワークのせいで、Anthropicから応答を受け取れないまま失敗やタイムアウトになることがあります。応答を受け取れなければヘッダーもなく、読めるrequest-idがありません。SDKは非ストリーミングのリクエストが10分を超えそうなら検証でとがめ、TCPのkeep-aliveも設定します。長い出力はストリーミングかMessage Batches APIで受けます。
ストリーミングでは、200を返した後にエラーイベントが届く場合があります。このときHTTPステータスによる分岐は効きません。200を返したレスポンスのヘッダーにもrequest-idが付いているので、IDはそこから控えられます。
anthropic-organization-idとanthropic-workspace-idも同じ経路で読める
request-idと並んで、レスポンスヘッダーにはanthropic-organization-idとanthropic-workspace-idも付きます。ワークスペースのドキュメントにある実際の形は次のとおりです。
HTTP/1.1 200 OK
request-id: req_018EeWyXxfu5pfWkrYcMdjWG
anthropic-organization-id: 0d0e7a3b-52f1-4c7e-9a51-3f6f2f7c1b9e
anthropic-workspace-id: wrkspc_01JwQvzr7rXLA5AGx3HKfFUJanthropic-workspace-idは、APIキーやアクセストークンが解決したワークスペースのID(wrkspc_接頭辞)です。Default Workspaceのときも値が入ります。付かないのは2つの場合です。資格情報がワークスペースに解決しないリクエスト(Admin APIなど)と、認証が終わる前に失敗した401のようなリクエストです。
読み取りの経路はrequest-idと同じです。複数のワークスペースを使い分けるチームでは、3つのIDを同じログ行に残しておくと、どの組織のどのワークスペースで起きたかを後から突き合わせられます。
「anthropic-workspace-id is required」の400が出たとき
ワークスペースに紐づかないAPIキー(複数ワークスペースにまたがるキー)を使うときは、リクエストごとにanthropic-workspace-idヘッダーを送る必要があります。ヘッダーを付けないと、400(invalid_request_error)が返ります。メッセージの冒頭は「anthropic-workspace-id is required」です。
対処は次の2つです。
- 送るワークスペースのIDを調べ、
anthropic-workspace-id: wrkspc_...をリクエストに付ける - 1つのワークスペース専用に作ったキーへ切り替える(このキーはヘッダーを省略できます)
ここでanthropic-workspace-idは、レスポンスで読むだけでなくリクエストで送る場面もあります。なお、anthropic-organization-idはレスポンスヘッダーとして読む値です。
Claude Platform on AWSでは2つのIDが返る
Claude Platform on AWS経由で呼ぶと、レスポンスにAWSのリクエストIDとAnthropicのリクエストIDが両方入ります。問い合わせ先によって使うIDが決まっています。
どちらのIDをどこへ渡すか
x-amzn-requestid
CloudTrailに記録されるIDです。AWSのツールで調べるときと、AWSサポートへ連絡するときに使います。
request-id
Anthropicサポートへ連絡するときに使います。
読み出し方はSDKで少し違います。Pythonはwith_raw_responseで受けたresponse.headers.get('x-amzn-requestid')でAWS側を、response.parse()したmessage._request_idでAnthropic側を読めます。TypeScriptは.withResponse()が返すresponse.headers.get("x-amzn-requestid")でAWS側を読みます。
CloudTrailでIDを引くときは、記録される種別に注意が必要です。ワークスペースや外部キーの操作は管理イベントとして既定で記録されます。推論やバッチなどの呼び出しはデータイベントの扱いで、明示的にデータイベントのログを設定しないとCloudTrailに残らず、追加料金もかかります。
curlで確かめるなら-iを付けると、本体の前にヘッダーが並びます。接続先はaws-external-anthropic.<リージョン>.api.awsで、署名は--aws-sigv4に渡し、リクエストヘッダーにanthropic-workspace-idを付けます。
エラーページのTypeScript例は.withResponse()の結果を{ response, request_id }で受け、request_idでAnthropic側のIDを取ります。Claude Platform on AWSのページは{ data, response }で受け、response.headers.get("request-id")でAnthropic側を読みます。どちらの書き方も2つのIDを取れます。片方だけを保存すると、CloudTrailの記録とAnthropicのチケットが別々のIDを指して突き合わせられません。
全呼び出しでrequest-idを記録する
問い合わせの場面まで待たず、普段からログに残しておくと後から突き合わせやすくなります。Pythonなら呼び出しを包む薄い関数を1つ挟みます。
import logging
logger = logging.getLogger("anthropic_client")
def create_message(**kwargs):
message = client.messages.create(**kwargs)
logger.info("request_id=%s model=%s", message._request_id, kwargs.get("model"))
return messageraw responseを使う言語では、呼び出しごとにraw response用の書き方へ切り替える必要があります。そこでSDKのミドルウェアの仕組みを使います。リクエスト送信前とレスポンス受信後に任意のコードを挟めます。ログ出力や独自の再試行などの横断処理向けに用意されたものです。ミドルウェアはPython・TypeScript・C#・Go・Java・PHP・Rubyの7言語すべてにあり、登録の書き方だけが言語ごとに違います。Goなら、ミドルウェアが*http.Responseを受け取るので、クライアントに一度登録するだけで全呼び出しのIDを出せます。
client := anthropic.NewClient(
option.WithMiddleware(func(req *http.Request, next option.MiddlewareNext) (*http.Response, error) {
res, err := next(req)
if err != nil {
return nil, err
}
slog.Info("received response", "status", res.StatusCode, "request_id", res.Header.Get("request-id"))
return res, nil
}),
)IDだけを単独で保存すると、発生時刻が分からず検索範囲を絞れません。時刻・モデル名と同じログ行にまとめておくと、問い合わせるときに「いつ・どのモデルの・どのリクエストか」が1行で答えられます。IDは文字列のまま保存して照合します。
よくあるつまずき
エラーオブジェクトのrequest_idとヘッダーのrequest-idを別物だと思う。ハイフンとアンダースコアの違いに見えますが、同じリクエストを指す同じ値です。ボディから読むか、ヘッダーから読むかの違いだけです。
429や529のたびに問い合わせる。サポート連絡がステータス別の対処に出てくるのは500だけです。429と529は、前の表の対処が先になります。ティア上限が原因の429は、支出上限の確認から入ります。
まとめ
サポートへの問い合わせにはrequest-idを添えます。時刻・モデル名・組織やワークスペースのIDと同じログ行に普段から残しておくと、あとで探す手間が減ります。Claude Platform on AWSでは、x-amzn-requestidも併せて保存します。エラー種別ごとの再試行設計はClaude APIのエラーハンドリング設計にあります。