When the Claude API returns 400 invalid_request_error, retrying is ineffective—400 indicates the request side was hard-rejected by the server, so you must directly modify the request body. In recent years, callers migrating from the GPT ecosystem have started receiving 400 errors even with the same SDK code, usually due to one of these four pitfalls: sampling parameters being hard-rejected, thinking blocks and signatures being tampered with, compatibility layer default value gaps, or non-compliant tool invocation response structures. This article provides identification and handling actions for the four causes of Claude API 400, along with suggestions for adaptation layer parameter whitelists and regression testing.
Conclusion first: Claude API 400 has only four sources
A 400 invalid_request_error from the Claude API indicates the request body itself was rejected by the server. Common triggers fall into four categories: sampling parameters being hard-rejected (e.g., passing deprecated temperature), thinking blocks and signatures being tampered with, compatibility layer default value gaps (e.g., missing max_tokens), and non-compliant tool invocation response structures. Each category has clear decision rules: "must delete," "must pass through as-is," and "must fill in." In recent years, Claude models have strengthened parameter validation and thinking block signature anti-tampering mechanisms, and callers migrating from the OpenAI ecosystem are most likely to encounter these four pitfalls.
Category 1: Sampling parameters hard-rejected by the server—can temperature still be passed?
Newer Claude models (such as the Claude 5 series) enforce hard validation on sampling parameters. According to the Anthropic Messages API reference: passing deprecated or non-default temperature, top_p, or specifying both simultaneously directly returns 400 invalid_request_error. In other words, the habit of globally configuring temperature=0.7 in the OpenAI chain cannot be blindly applied—for models that do not support this parameter, this field will be directly rejected.
Action: Delete, not change the value. If the model does not support the parameter, remove it from the request body; do not attempt to replace it with 0.8 or 0.1, as that will continue to trigger the same error. If you reuse a single request construction code across multiple models, you need to maintain a parameter whitelist per model capability.
| Parameter | Typical Trigger Scenario | Action | Layer |
|---|---|---|---|
| temperature | Pass non-default value or use with top_p | Delete field | Client/Gateway Cleanup |
| top_p | Pass non-default value or use with temperature | Delete field | Client/Gateway Cleanup |
| max_tokens | Missing (Anthropic requires it) | Explicitly fill in | Client/Gateway Completion |
| thinking/signature | Historical pass-back tampered or removed | Pass through as-is | Client/Gateway Pass-through |
Category 2: Thinking blocks and signatures altered—multi-turn history directly blocked
In multi-turn conversations involving thinking processes, the Claude API enforces validation of the integrity and order of thinking blocks and their signature fields. The thinking block in historical assistant messages must be returned unmodified; any tampering, removal, or reordering of the signature will result in a 400 error. If your error originates from extended thinking parameters, the solution is not to change the parameter values but to ensure the thinking block is passed back intact.
Decision: Think-related content should never be deleted or rewritten; preserve the entire historical structure and pass it back as-is. To save tokens, you can only drop entire old turns, not strip thinking or signature from retained turns.
Common breakage points include relay layers or self-developed context compression logic—filtering out thinking blocks to save tokens, which triggers signature validation. If you need to reduce context, you can truncate old history before sending, but the included thinking blocks and signatures must remain original. For more on passing thinking history in multi-turn conversations, refer to How to Pass Thinking History in OpenAI SDK Compatible Multi-turn Conversations.
Category 3: What causes 400 when calling Claude with OpenAI SDK?—max_tokens and injected parameters
The most common root cause of 400 errors when calling Claude via the OpenAI SDK is a mismatch in parameter defaults and protocol mapping. According to OpenRouter's parameter conversion documentation: the Anthropic Messages API requires explicit max_tokens (while it is optional in OpenAI specifications), and the sampling parameters that the OpenAI SDK includes by default (such as temperature=0.7) are forwarded directly, triggering compliance hard rejection.
Compatibility layer actions: Add the required max_tokens value in the adaptation layer and clean sampling parameters in the request body. Note that some SDKs inject default parameters at the application layer; you need to confirm whether these parameters are actually sent to the server. Sending the same request to the official endpoint and a relay endpoint can quickly reveal which fields are SDK-injected.
Category 4: What does a 400 due to non-compliant tool invocation response structure look like?
In the Tool Use flow, the Claude API requires that after the tool_use block, there must be a pure tool_result user message. If the corresponding tool_result is missing, tool_use_id does not match, or unaligned text is inserted in the same turn, the server immediately returns 400.
Three most error-prone spots in agent loops:
- Tool results are not passed back to the API but directly concatenated into the next user message.
tool_use_idcopied incorrectly or lost.- Extra text (e.g., status prompts) inserted between
tool_useandtool_result.
Ensure that every tool_use in the tool invocation chain has a corresponding tool_result, and the structure is pure. For practical guidance on building a complete tool call loop, refer to Tool Call API.

Figure 1: Four-category 400 cause determination flow—first look at the rejected field, then reproduce with a minimal request body.
Three-step on-site determination: How to distinguish the four types of 400 on the spot
When receiving a 400, quickly locate the issue with the following steps:
- Read the response body: Check the error information to determine whether the rejected field is
temperature,signature, ortool_result, but do not rely on specific error strings (official strings may change anytime). - Reproduce with a minimal request: Keep only
model+messages+max_tokens. If no 400 occurs, the issue lies in an optional field or structure. - Binary add back parameters: Add back sampling parameters, historical thinking blocks, and tool call results one by one, testing at each step until the 400 reproduces, thereby locking in the variable.
Note: 400 differs from 429 and timeouts. 400 is a request body issue and retrying is ineffective; 429 is rate limiting, and retrying later may succeed.
How to write an adaptation layer: Maintain parameter whitelists per model rather than scattered if-else
For compatibility when sharing a single set of request parameters across multiple models, the approach is to maintain a whitelist per model capability rather than scattered if-else. Converge the four causes into engineering practices: in the gateway/adaptation layer, maintain an allowed parameter whitelist based on model capabilities, clean incompatible sampling fields before forwarding, fill in required fields (such as max_tokens), and pass through signed thinking blocks and tool call structures intact. For relay layers, there are only three handling options for parameters—pass through as-is, silently drop, or modify; the latter two can turn deterministic 400s into hard-to-reproduce behavioral anomalies. To determine whether a relay endpoint passes parameters through intact, refer to the comparison method in How to Choose an AI Relay.
Division of labor between client deletion and gateway cleanup: If the client directly faces multiple models, you can delete fields based on model branches; if using a unified gateway, let the gateway clean based on the whitelist while the client remains generic. Regardless, do not silently drop or rewrite thinking blocks and tool_use structures.
# 伪代码:按模型能力清洗请求体
def clean_request(model, request_body):
whitelist = get_whitelist(model) # 从模型能力表读取
# 1. 剔除白名单外的采样字段
for key in ['temperature', 'top_p']:
if key not in whitelist and key in request_body:
del request_body[key]
# 2. 缺省时补齐 max_tokens
if 'max_tokens' not in request_body:
request_body['max_tokens'] = 4096 # 示例值
# 3. thinking 块与 tool_use/tool_result 原样透传,不做任何改写
return request_body
Figure 2: Data flow of adaptation layer whitelist cleaning and signature/tool structure pass-through.
Four must-test items after changes and regression checklist before switching endpoints
It is recommended to solidify the following four items as a minimal set of request test cases in CI, running them before switching models or endpoints:
- Non-streaming request: Ensure basic parameter cleanup and completion take effect.
- Streaming request: Verify that thinking blocks and tool calls are passed through correctly in streaming mode.
- Complete tool call loop: Run the full chain from
tool_usetotool_result. - Multi-turn history (including thinking blocks) pass-back: After passing signed history blocks intact, verify subsequent conversations work.
Before switching models or endpoints, send the same request to both the official endpoint and a relay endpoint to compare parameter pass-through. For example, use NexAIX's OpenAI-compatible interface (base_url https://api.nexaix.net/v1) with test credits to perform a parameter pass-through verification. When the model is overloaded, it returns a standard 429 rather than silently switching models, and the model field in the response corresponds to the actual executing model, allowing you to separate 400 from downgrade issues for attribution. For related rate limit identification, refer to Handling AI API 429.
The conclusions in this article are based on Anthropic's official Messages API reference and error code documentation, as well as OpenRouter's error handling and parameter conversion documentation; for specific model parameter support, refer to the official documentation's current version.
Frequently Asked Questions
Is temperature completely unsettable?
For newer Claude models, temperature and top_p are generally not settable; passing them results in a 400. To control randomness, check whether the model supports the thinking parameter or other sampling methods, as per official documentation.
Should I retry on a 400?
No. 400 indicates the request body was hard-rejected by the server; retrying will not succeed. Modify the request body immediately instead of backing off and retrying.
Can I prune thinking history to save tokens?
You can trim old turns, but the thinking blocks and signature that have been sent must be retained intact. It is recommended to compress before the API layer rather than deleting thinking blocks.
Should the gateway filter unsupported parameters for me?
Ideally yes, but only if the gateway maintains a whitelist based on model capabilities and fully passes through signatures and tool structures. If the gateway silently drops them, it may turn 400 errors into harder-to-diagnose anomalies, so it is recommended to test first. Relay endpoints like NexAIX return a standard 429 when overloaded rather than silently switching models, which can help separate 400 from downgrade issues.
What should I change when calling Claude with the OpenAI SDK?
At minimum, add max_tokens (required), remove possibly injected temperature/top_p, ensure the message structure after tool_use is pure, and return the thinking block intact.
NexAIX-官方博客
Comments(0)