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.
Symptoms
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.
Likely causes
- 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.
Diagnostic procedure
- 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"}]}"Remediation
- 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)Verification
- 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.
Sensitive diagnostic data
- 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.
View documentation scope