# OpenAI 兼容接口

https://modelportal.ai/docs/api-openai?lang=zh

基础地址 `https://modelportal.ai/v1`，鉴权 `Authorization: Bearer YOUR_API_KEY`。请求与响应格式与 OpenAI API 一致，下面只列平台相关的字段和差异。

## POST /v1/chat/completions

对话补全，支持流式。

| 字段 | 类型 | 必填 | 说明 |
| --- | --- | --- | --- |
| `model` | string | 是 | 模型 ID 或别名 |
| `messages` | array | 是 | 对话消息，支持文本、图片和工具结果 |
| `stream` | boolean | 否 | 为 `true` 时以 SSE 返回，见[流式输出](/docs/streaming) |
| `stream_options` | object | 否 | `{"include_usage": true}` 时最后一个分块带 `usage` |
| `max_tokens`、`max_completion_tokens` | integer | 否 | 最大输出；不填时平台按模型上限和可用余额补一个值 |
| `temperature`、`top_p`、`top_k`、`seed`、`n`、`logprobs`、`frequency_penalty`、`presence_penalty` | — | 否 | 采样参数，报价不支持的不会被选中，见[参数映射表](/docs/parameter-mapping) |
| `tools`、`tool_choice` | — | 否 | 工具调用，见[工具调用](/docs/tool-calling) |
| `response_format` | object | 否 | `json_object` 或 `json_schema`，见[结构化输出](/docs/structured-output) |
| `reasoning`、`reasoning_effort` | — | 否 | 推理控制，见[推理控制](/docs/reasoning) |
| `provider` | object | 否 | 路由偏好，转发前删除，见[供应商选择](/docs/provider-routing) |

`user`、`safety_identifier`、`prompt_cache_key` 可以照常传，平台在转发前删掉。

```json
{
  "id": "chatcmpl-...",
  "object": "chat.completion",
  "model": "MODEL_ID",
  "choices": [{"index": 0, "message": {"role": "assistant", "content": "你好！"}, "finish_reason": "stop"}],
  "usage": {"prompt_tokens": 9, "completion_tokens": 4, "total_tokens": 13, "cost": 0.000013},
  "provider": "PROVIDER_ID",
  "attempts": [{"provider": "PROVIDER_ID", "endpoint": "ENDPOINT_ID", "status": 200, "cost": 0.000013}]
}
```

响应里的 `model` 是规范模型 ID，`usage` 是计费用量：输入含缓存读写，输出含推理。`usage.cost` 是这次的扣费（USD），`provider`、`attempts` 是承接的供应商和每次尝试；流式时每个分块都带 `provider`，`attempts` 和 `usage.cost` 在带 `usage` 的最后一个分块里。响应头见[接口概览](/docs/api-overview)。

## POST /v1/responses

Responses 接口，支持流式，只支持无状态调用：

- `store` 一律按 `false` 处理，响应里如实返回 `"store": false`。
- 带 `previous_response_id`、`conversation` 或 `background` 返回 400 `stateful_not_supported`。需要多轮时，自己把历史放进 `input`。
- `POST /v1/responses/input_tokens` 计算输入 token 数，不计费。

字段与 OpenAI 一致，`model`、`input` 必填，最大输出用 `max_output_tokens`，结构化输出用 `text.format`。

## POST /v1/embeddings

生成向量，模型要具备向量能力，否则返回 404 `model_not_found`。`model`、`input` 必填，`input` 可以是字符串或字符串数组。

## GET /v1/models

返回这把密钥能调用、且有可用报价的模型，见[模型列表接口](/docs/api-models)。

## 错误码

| HTTP | 错误码 | 常见原因 |
| --- | --- | --- |
| 400 | `invalid_request`、`unsupported_parameter`、`stateful_not_supported` | 字段不合法、参数不被支持、有状态调用 |
| 401 | `invalid_api_key`、`key_inactive` | 密钥问题 |
| 402 | `insufficient_balance`、`budget_exceeded` | 余额或消费上限 |
| 403 | `key_restricted`、`request_blocked` | 密钥限制、风控 |
| 404 / 410 | `model_not_found`、`model_retired` | 模型不可用 |
| 422 | `no_eligible_endpoint` | 没有满足约束的报价 |
| 429 | `rate_limited`、`capacity_exhausted` | 限流或满载 |
| 502 | `upstream_failed` | 上游失败 |

错误体为 `{"error": {"message", "type", "code", "request_id"}}`，完整说明见[常见错误](/docs/errors)。
