Direct answer
A 400 response means a server received the request but could not accept it under the selected API contract. Preserve the structured error before reducing the payload.
What this guide helps you solve
Resolve invalid_request_error, malformed JSON, unsupported parameters, and endpoint mismatches that produce HTTP 400.
Confirm the symptom and blast radius
The request returns 400 immediately, often with invalid_request_error, a parameter name, or a JSON parsing message.
A model-list request may work while generation fails only when tools, streaming, response_format, images, or advanced sampling fields are present.
- Capture the status or exception, response body, request ID, UTC time, client version, and final host before changing configuration.
- Compare one minimal request with the failing workflow to determine whether the issue is global, model-specific, or feature-specific.
- Keep credentials, full prompts, customer data, and private file contents out of screenshots and support bundles.
Common causes and ownership boundaries
Treat the error as evidence from one layer, not as proof that every downstream component failed. These are the highest-value causes to test first.
- Malformed or double-encoded JSON, a missing required field, or a value with the wrong type.
- A base URL that combines with the SDK resource path incorrectly, producing the wrong endpoint.
- A model or compatible gateway that does not implement an optional field or modality.
- Responses API fields sent to Chat Completions, or the reverse.
Run a layered minimal diagnosis
Start with a request that has the fewest moving parts. Preserve the same account, API host, and target model while removing optional features.
Change one variable at a time and retain the raw status, headers, response body, and timing. This separates client serialization from gateway and upstream behavior.
- 01Establish the boundaryRecord the final URL, Content-Type, raw error body, and request ID.
- 02Create a baselineSend only the model and one plain-text input with curl.
- 03Compare one variableCompare curl with the SDK request to isolate serialization.
- 04Record decisive evidenceRestore stream, tools, output format, and sampling fields one at a time.
API_BASE_URL='https://<your-api-host>/v1'
MODEL_ID='<YOUR_MODEL_ID>'
curl -sS -D /tmp/api-headers.txt "$API_BASE_URL/chat/completions" -H "Authorization: Bearer ${API_KEY:?set API_KEY first}" -H 'Content-Type: application/json' --data "{"model":"$MODEL_ID","messages":[{"role":"user","content":"ping"}]}"Apply the fix at the confirmed root cause
Make the smallest change that addresses the proven layer. Avoid hiding deterministic configuration failures behind broad retries or disabled validation.
- 01Correct the failing layerCorrect the base URL, JSON type, or missing field identified by the minimal reproduction.
- 02Restore required behaviorBuild the payload for the actual target API instead of mixing Responses and Chat Completions shapes.
- 03Remove temporary workaroundsRestore only capabilities that the selected model and gateway explicitly support.
from openai import OpenAI
client = OpenAI(api_key="<YOUR_API_KEY>", base_url="https://<your-api-host>/v1")
result = client.chat.completions.create(
model="<YOUR_MODEL_ID>",
messages=[{"role": "user", "content": "ping"}],
)
print(result.choices[0].message.content)Verify the repair, not just one successful call
Repeat the original path after the minimal check succeeds, then verify stable behavior under normal streaming, concurrency, and timeout conditions.
- The minimal request returns the expected status and response schema.
- The final URL contains the API version and resource path exactly once.
- Each optional parameter passes when restored independently.
- Logs retain a sanitized request ID and error type without secrets or private prompts.
Security boundaries and escalation evidence
Collect enough evidence to reproduce and escalate the failure without exposing credentials or weakening transport, permission, and validation controls.
- Never print the Authorization header while comparing requests.
- Redact prompts, uploaded content, and customer identifiers from diagnostics.
- Do not retry deterministic 400 responses indefinitely.
- Escalate with UTC time, request ID, endpoint, model ID, and a sanitized minimal body.
Official sources and verification scope
This guide is grounded in protocol specifications and official client documentation. Error text, retry headers, and configuration fields may change by service or client version; verify the sources and redact logs and request samples before sharing.
Read the verification methodology