OpenAI API 400 错误怎么办?请求参数与 JSON 格式排查
简答:OpenAI API 返回 400,通常表示请求已经到达接口,但请求格式、字段、参数值、端点或请求体不符合当前 API 的要求。最快的处理方法是先读取完整错误 JSON 中的 error.message、error.param 和 error.code,再用一个只保留 model 与 input 或 messages 的最小请求复现,最后逐个恢复参数。
定义:OpenAI API 400 Bad Request 是客户端请求不符合接口要求时返回的 HTTP 状态码,常见原因包括缺少必填字段、字段类型错误、JSON 无效、端点与请求体不匹配、模型不支持参数或请求头格式异常。
先试这一步:用最小请求判断责任层
本文为第三方 AI API 接入指南,内容按 2026-10-31 检索到的公开文档核验。先不要修改业务代码,也不要连续重试。把请求缩减到一个模型、一个简单文本输入和必要认证,观察是否仍然返回 400。
官方错误码文档将 BadRequestError 定义为请求格式错误或缺少必要参数,并建议根据错误信息检查参数、编码、格式和请求大小。可参考 OpenAI API Error codes。
Responses API 最小 curl:
curl https://api.openai.com/v1/responses -H "Authorization: Bearer $OPENAI_API_KEY" -H "Content-Type: application/json" -d '{"model":"<MODEL_ID>","input":"Reply with one word: OK"}'
Chat Completions 最小 curl:
curl https://api.openai.com/v1/chat/completions -H "Authorization: Bearer $OPENAI_API_KEY" -H "Content-Type: application/json" -d '{"model":"<MODEL_ID>","messages":[{"role":"user","content":"Reply with one word: OK"}]}'
成功判定不要只看 HTTP 200,也要确认响应是合法 JSON,并且包含对应接口的输出字段。若最小请求成功,再每次只恢复一个业务参数;恢复某个字段后首次出现 400,该字段或它与模型、端点的组合就是重点嫌疑。
400 错误速查:先看错误对象,再决定怎么改
| 错误信息或现象 | 优先检查 | 处理方式 |
|---|---|---|
BadRequestError、invalid_request_error | 必填字段、字段拼写、类型、格式 | 读取 error.message 与 error.param,对照当前接口文档修改 |
Invalid service_tier argument | service_tier 与项目允许范围 | 删除该字段或改成项目允许的值,并检查项目设置 |
| 提示 JSON 无效 | 单引号、尾逗号、转义、双重序列化 | 打印最终发送的字符串,用 JSON 解析器验证 |
| 提示缺少 input 或 messages | Responses 与 Chat Completions 字段混用 | Responses 使用 input,Chat Completions 使用 messages |
| 只在加入某参数后失败 | 模型是否支持该参数、枚举值和数值范围 | 删除该参数确认,再查对应接口和模型能力说明 |
| 客户端显示 400,但服务端看不到请求 | 代理、SDK、网关或本地序列化层 | 用 curl 直连复现,并记录最终 URL、请求头名称和脱敏后的请求体 |
错误对象中的 message 通常解释失败原因,param 可以指向具体参数,code 则可能提供更细的分类。不要只复制异常类名;请保留完整错误响应,但删除密钥、Authorization、用户输入和文件内容。
第一层排查:确认 URL、方法和接口字段没有混用
当前 API Reference 把 Responses、Chat Completions、Realtime 和管理接口分开列出。直接模型请求应先确认你选择的是哪一个 API surface,再核对对应的端点和请求 schema。官方参考页说明,Responses 用于直接模型请求、工具、音频、图像和文本输入等场景,同时仍单独列出 Chat Completions 接口。参考 OpenAI API Reference Overview。
- 请求方法通常应为
POST;如果 SDK 或代理改成了其他方法,先用 curl 验证。 - 确认 URL 的路径与请求体属于同一个接口,不要把
messages直接发送到只接受input的请求,也不要把 Responses 的字段原样复制到 Chat Completions。 - 确认 Base URL 拼接没有重复路径,例如配置已经包含
/v1时,不要再拼接一次。 - 确认请求头包含
Content-Type: application/json,认证头使用当前接口文档要求的形式。 - 如果使用 OpenAI 兼容网关,不能假设网关支持官方接口的全部字段;先以网关提供的 schema 和实际响应为准。
如果你使用的是 SDK,建议先记录 SDK 最终请求的 HTTP 方法、完整路径、状态码和响应体。不要把业务对象当成最终请求,因为 SDK 可能会重命名字段、过滤空值、添加默认参数或重新序列化 JSON。
第二层排查:JSON、编码和双重序列化
400 很多时候不是业务参数错误,而是发送到服务器的字节与预期 JSON 不同。常见问题包括使用单引号包裹 JSON、属性名未加双引号、结尾多了逗号、换行或反斜杠转义错误,以及把 JSON 字符串再次编码成 JSON 字符串。
- 合法 JSON:对象键和字符串值使用双引号,不能使用 JavaScript 对象字面量中的未加引号键名。
- 避免双重序列化:如果 HTTP 客户端已经会序列化对象,不要先手动执行一次
JSON.stringify后再把结果交给同一个 JSON 参数。 - 检查 Content-Type:发送 JSON 时应明确设置
application/json;不要把 JSON 文本当作表单数据提交。 - 检查 UTF-8:请求体应使用兼容的 UTF-8 编码,尤其注意从文件读取的不可见字符、BOM 和异常控制字符。
- 检查大小:错误码文档建议同时检查请求数据的编码、格式和大小;如果怀疑请求过大,删除文件、工具定义和历史上下文后做最小复现。
Python 最小示例:
import os; from openai import OpenAI; client = OpenAI(api_key=os.environ["OPENAI_API_KEY"]); response = client.responses.create(model="<MODEL_ID>", input="Reply with one word: OK"); print(response.output_text)
JavaScript 最小示例:
const client = new OpenAI({ apiKey: process.env.OPENAI_API_KEY }); const response = await client.responses.create({ model: "<MODEL_ID>", input: "Reply with one word: OK" }); console.log(response.output_text);
如果 Python 或 JavaScript 失败而 curl 成功,优先检查 SDK 版本、环境变量是否为空、自动加入的默认参数和最终序列化结果。若三者都失败,再回到端点、模型和参数兼容性。
第三层排查:必填字段、类型、枚举值和模型兼容性
400 不一定意味着整个请求都错了,也可能只是某个字段的值不被当前端点或模型接受。按下面顺序逐项删除并恢复:
- 只保留
model与最简单的input或messages。 - 恢复系统提示、历史消息和用户输入,确认字符串、数组和对象层级正确。
- 恢复输出格式、工具、结构化输出、视觉输入等高级参数。
- 最后恢复 token 参数、服务层级、流式选项和业务自定义字段。
重点检查以下类型错误:
model是空字符串、拼写错误,或使用了当前项目不可用的模型标识。messages不是数组,消息缺少role或content类型不符合接口要求。input被错误地传成双重编码字符串,或者把只适用于另一接口的消息结构直接嵌套进去。- 枚举字段使用了文档之外的值,数值字段传成字符串,或把
null传给不接受空值的字段。 - 工具、结构化输出、图像输入或 token 参数与当前模型能力不匹配。没有直接证据时,不要根据其他模型的经验推断支持范围,应以对应接口和模型文档为准。
service_tier被项目限制时,官方错误码文档会将其标为 400,并可能在error.param中指向service_tier。此时检查项目允许的服务层级,或先移除该参数。参考 官方错误码说明。
第四层排查:请求头、请求 ID 与代理链路
API Reference 建议在生产环境记录服务端返回的 x-request-id,用于后续定位;同时可以通过 X-Client-Request-Id 传入自己的追踪 ID。该自定义 ID 只能使用 ASCII 字符且长度不超过 512 个字符,否则请求本身可能返回 400。相关限制见 API Reference 的 Debugging requests。
建议记录以下脱敏信息:请求时间和时区、HTTP 方法、最终 URL、接口名称、模型标识、状态码、error.type、error.code、error.param、x-request-id,以及请求体中各字段的类型和长度。不要记录 API Key、完整 Authorization、用户原文、文件内容或完整提示词。
如果 curl 直连成功,但应用失败,按“业务对象→SDK→代理或网关→HTTP 客户端→服务器”的顺序比较。逐层保存字段列表和序列化后的 JSON 结构,不需要保存敏感值。对于代理或兼容网关,400 可能由网关自己的校验产生,不能直接当成官方接口规则。
400 与其他状态码的区别:不要用错排查方法
| 状态码 | 通常表示 | 是否优先修改请求 JSON |
|---|---|---|
| 400 | 请求格式、参数、端点组合或请求头值不符合要求 | 是,先读错误对象并最小化请求 |
| 401 | 认证信息无效、密钥不正确或组织项目不匹配 | 否,先检查 API Key、组织和项目 |
| 403 | 权限、地区或访问策略不允许 | 通常不是,先查权限与访问条件 |
| 413 | 请求体过大,具体边界以实际接口或中间层响应为准 | 减少输入、文件、历史消息或工具定义 |
| 429 | 速率、额度、支出限制或使用量限制 | 否,按限速和额度信息处理 |
| 500/503 | 服务端处理失败或模型暂时不可用 | 通常不是,先查看状态并按官方建议重试 |
官方支持文档建议排查错误时按模型、服务层级和项目过滤,并使用 HTTP Requests 视图观察状态码和错误率;如果客户端显示错误,但服务健康数据中没有对应请求,可能是请求没有到达服务端,需检查代理、网络或本地超时。参考 Troubleshooting API Errors and Latency。
Postman 与回归测试:把一次排错变成可重复检查
使用 Postman 时新建一个 POST 请求,填写实际端点,添加 Authorization 和 Content-Type 请求头,在 Body 中选择 raw 与 JSON,然后只放入最小请求。先点击发送确认基础请求,再一次只添加一个字段。不要直接导入包含真实密钥的工作区文件,也不要把密钥写进团队共享环境。
修复后可以保留一个脱敏回归用例:固定端点、使用环境变量注入密钥、使用可核验的模型占位符或项目允许的模型、检查状态码和关键响应字段。测试失败时打印错误类型和请求 ID,而不是打印 Authorization 和完整用户输入。
截至 2026-10-31,最稳妥的排查闭环仍是:确认 Key、Base URL、模型和真实请求地址;发出最小请求;读取错误对象;按字段逐个恢复;最后再检查 SDK、代理和网关。这样可以把“400 很笼统”的问题转化为一个具体字段或具体链路。
常见问题
OpenAI API 返回 400 是不是 API Key 错了?
通常不是。API Key 错误更应先按 401 方向排查;400 更常见于请求体、字段、端点组合、参数值、请求头自定义字段或请求大小问题。但如果中间网关改写了状态码,仍应以完整响应体和实际请求链路为准。
Responses API 和 Chat Completions 的请求参数可以混用吗?
不能直接混用。Responses API 的最小请求使用 model 与 input,Chat Completions 使用 model 与 messages。应先确认实际 URL,再按照该接口的请求 schema 组织 JSON。
为什么只加了 service_tier 就返回 400?
官方错误码文档列出了 Invalid service_tier argument。项目或组织可能不允许请求解析到的服务层级;检查项目设置和组织限制,或删除该字段后重新测试。
JSON 看起来正确,为什么仍然是 400?
你看到的业务对象不一定是最终发送内容。常见原因包括 SDK 二次序列化、代理改写、空环境变量、错误的 Content-Type、不可见字符、字段类型变化,以及把一个 JSON 字符串又编码成 JSON 字符串。建议用 curl 直连,并记录脱敏后的最终请求结构。
400 错误需要不断重试吗?
不建议对同一个未改变的 400 请求盲目重试。400 通常是确定性的客户端请求问题,应先修正字段或格式;只有在确认请求内容已改变,或中间层存在暂态改写时,才重新发送。429、500 和 503 则应按各自的限流或服务端处理方式分流。
排查 400 时应该保存哪些日志?
保存时间和时区、端点、模型、状态码、错误类型、错误代码、错误参数、服务端 x-request-id 和自定义追踪 ID。不要保存 API Key、Authorization、完整用户输入、文件内容或完整敏感提示词。
相关阅读
- 继续排查 OpenAI API 401 鉴权错误
- 如果提示模型不存在,查看 404 模型排查步骤
- 先用最小请求测试 OpenAI 兼容接口
- 在 LangChain 中检查兼容接口配置与请求参数
- 在 Dify 中核对 Base URL、模型名和 API Key