# APIPace 文档全文
本文件是 https://docs.apipace.com 全部页面的 Markdown 拼接,按站内顺序排列。机器可读的接口契约在 https://api.apipace.com/docs/openapi.json。
---
来源:https://docs.apipace.com/docs/quickstart
# 快速开始
五分钟从零发出第一个请求:拿 key、选别名、用你手上任何一个 OpenAI 或 Anthropic 客户端打过来。
## 一张表看懂
| 项 | 值 |
|---|---|
| Base URL | `https://api.apipace.com` |
| OpenAI 协议 | `POST /v1/chat/completions` |
| Anthropic 协议 | `POST /v1/messages` |
| Gemini 原生 | `POST /v1beta/models/{别名}:generateContent` |
| 图片生成 | `POST /v1/image-tasks`(异步任务) |
| 鉴权方式 A | `Authorization: Bearer ak-…` |
| 鉴权方式 B | `x-api-key: ak-…` |
| 控制台 | |
两种鉴权效力完全相同,任选一种;同一把 key 在两种协议上都能用。
## 1. 注册
去 ,三步:
1. **填邮箱**,点发送验证码。邮箱会收到一封 6 位数字的信,**10 分钟内有效、只能用一次**。
2. **填验证码和密码**(至少 8 位)。
3. **勾选同意**《服务条款》和《隐私政策》——不勾选注册不了。
提交后直接就是登录状态,系统同时给你建好自己的租户和一个默认项目 / 应用。有邀请码可以在「有邀请码?点这里填写」里填,没有也能注册。
忘记密码走 ,同样是邮箱收码。**重置会把这个账号已有的登录全部踢下线**,所以重置完其它设备要重新登录。
## 2. 拿一把 key
进控制台的「API Key」页新建。**创建时完整 key 只显示一次**,离开页面就看不到了,请立刻存进你的密码管理器或环境变量。
key 建好之后建议写进环境变量,下面所有例子都假设它在 `$APIPACE_KEY` 里:
```bash
export APIPACE_KEY="ak-…"
```
## 3. 选一个别名
`model` 字段填**别名**,不是厂商的原始模型名。当前可用别名以 `GET /v1/models` 实时返回为准:
```bash
curl https://api.apipace.com/v1/models -H "x-api-key: $APIPACE_KEY"
```
```json
{"object":"list","data":[
{"id":"claude-sonnet-4.6","object":"model","created":1789534530,"owned_by":"apipace"},
{"id":"kimi-k3","object":"model","created":1789534530,"owned_by":"apipace"}
]}
```
(`owned_by` 是为兼容 OpenAI 客户端留的占位字段,恒为 `apipace`,没有别的含义。)
**默认只列对话别名**——也就是可以直接填进 `model` 发对话请求的那些。Gemini 原生和图片这类不走对话协议的能力不在默认列表里,填进对话请求只会拿到 400。
想看全部,加 `include=all`,每条会多一个 `capabilities` 说明它能怎么用:
```bash
curl "https://api.apipace.com/v1/models?include=all" -H "x-api-key: $APIPACE_KEY"
```
```json
{"object":"list","data":[
{"id":"claude-sonnet-4.6","object":"model","created":1789534530,"owned_by":"apipace",
"capabilities":["chat","stream","tools"]},
{"id":"gemini-2.5-pro","object":"model","created":1789534530,"owned_by":"apipace",
"capabilities":["gemini_native","video_understanding"]},
{"id":"gpt-image-2-official","object":"model","created":1789534530,"owned_by":"apipace",
"capabilities":["image_generation"]}
]}
```
| capability | 意思 | 走哪个接口 |
|---|---|---|
| `chat` | 对话 | `/v1/chat/completions`、`/v1/messages` |
| `stream` | 支持流式 | 同上,`stream: true` |
| `tools` | 支持工具调用 | 同上 |
| `gemini_native` | 只认 Gemini 原生形状 | `/v1beta/models/{别名}:generateContent` |
| `video_understanding` | 能读视频 | 同上 |
| `image_generation` | 生成图片 | `/v1/image-tasks` |
当前在售的别名和单价另有一份免鉴权的清单:
```bash
curl https://api.apipace.com/v1/pricing
```
人看的版本在 。
如果这把 key 设了模型白名单,白名单之外的别名在 `/v1/models` 里就看不到,填了会返回 `MODEL_NOT_FOUND`。
## 4. 发第一个请求
两种协议二选一,看你的客户端和 SDK 讲哪一种。
### OpenAI 协议
```bash
curl https://api.apipace.com/v1/chat/completions \
-H "Authorization: Bearer $APIPACE_KEY" \
-H "content-type: application/json" \
-d '{"model":"claude-sonnet-4.6","max_tokens":16,"messages":[{"role":"user","content":"用一个词打招呼"}]}'
```
```json
{
"id": "req_01M2M6P1SDGR2X27H0MZRNW0HE",
"object": "chat.completion",
"created": 1789531981,
"model": "claude-sonnet-4.6",
"choices": [{"index":0,"finish_reason":"stop","message":{"role":"assistant","content":"你好! 👋"}}],
"usage": {"prompt_tokens":16,"completion_tokens":11,"total_tokens":27},
"request_id": "req_01M2M6P1SDGR2X27H0MZRNW0HE",
"billable_units": {"input_tokens":16,"output_tokens":11,"usage_source":"upstream"}
}
```
### Anthropic 协议
```bash
curl https://api.apipace.com/v1/messages \
-H "Authorization: Bearer $APIPACE_KEY" \
-H "anthropic-version: 2023-06-01" \
-H "content-type: application/json" \
-d '{"model":"claude-sonnet-4.6","max_tokens":16,"messages":[{"role":"user","content":"用一个词打招呼"}]}'
```
```json
{
"id": "req_01M2M6NZBQRN748G5NXAMRF6W1",
"type": "message",
"role": "assistant",
"model": "claude-sonnet-4.6",
"content": [{"type":"text","text":"你好!👋"}],
"stop_reason": "end_turn",
"usage": {"input_tokens":16,"output_tokens":9,"cache_creation_input_tokens":0,"cache_read_input_tokens":0},
"request_id": "req_01M2M6NZBQRN748G5NXAMRF6W1",
"billable_units": {"input_tokens":16,"output_tokens":9,"usage_source":"upstream"}
}
```
两个响应体都是原样透传,只多了两个平台字段:`request_id` 和 `billable_units`。标准 SDK 不认识的字段会被忽略,不影响解析。
## 5. 查这一笔扣了多少
响应体里有 token,**没有钱**。钱拿 `request_id` 去查:
```bash
curl https://api.apipace.com/v1/requests/req_01M2M6NZBQRN748G5NXAMRF6W1 \
-H "x-api-key: $APIPACE_KEY"
```
```json
{
"request_id": "req_01M2M6NZBQRN748G5NXAMRF6W1",
"status": "FINALIZED",
"model": "claude-sonnet-4.6",
"stream": false,
"usage": {"input_tokens":16,"output_tokens":9,"total_tokens":25},
"billable_units": {"input_tokens":16,"output_tokens":9,"request_count":1,"usage_source":"upstream"},
"sales_amount": 1365,
"currency": "CNY",
"route_id": "01M2M6NZC9C8HYDJFE0ZAFEP4R",
"latency_ms": {"total":1288,"upstream_first_byte":1274,"upstream_total":1274,"platform_overhead":14},
"created_at": "2026-09-16T04:12:59.134049Z",
"adjustments": []
}
```
`sales_amount` 是微元:1,365 微元 = ¥0.001365。请求一返回记录就已落库,可以立刻查,不用等。完整口径见计费与账单。
## 下一步
- 你用的是什么客户端,就翻哪一篇接入指南——Claude Code、Codex CLI、Cursor、Cline、Cherry Studio、ChatBox、Dify、沉浸式翻译都有单独一页。
- 要生成图片看图片生成;要用 Gemini 的视频理解看Gemini 原生接口。
- 报错了先翻限制与错误码,那里有全部错误码和该怎么处理。
- 每个接口的完整字段定义在 API 参考,右侧可以填 key 直接发一次真实请求。
---
来源:https://docs.apipace.com/docs/claude-code
# 接入 Claude Code
Claude Code 走 **Anthropic 协议**,几个环境变量就能把它整个指过来,不用改配置文件。
## 配置
```bash
export ANTHROPIC_BASE_URL="https://api.apipace.com"
export ANTHROPIC_AUTH_TOKEN="ak-…"
# 三个别名各指一个真实存在的别名
export ANTHROPIC_MODEL="claude-sonnet-4.6"
export ANTHROPIC_DEFAULT_SONNET_MODEL="claude-sonnet-4.6"
export ANTHROPIC_DEFAULT_OPUS_MODEL="claude-opus-4.6"
export ANTHROPIC_DEFAULT_HAIKU_MODEL="claude-sonnet-4.6"
claude
```
写进 `~/.zshrc` / `~/.bashrc`,或者放进 `~/.claude/settings.json` 的 `env` 块,都行。
> 注意:**项目级** `.claude/settings.json` 里的 `env` 要等目录信任提示通过之后才生效,会出现「curl 明明通了、Claude Code 还在要你登录」。凭据放 shell 或用户级 settings 最稳。
## 变量都是干什么的
| 变量 | 填什么 |
|---|---|
| `ANTHROPIC_BASE_URL` | `https://api.apipace.com`,**不带 `/v1`**——Claude Code 自己会拼 `/v1/messages` |
| `ANTHROPIC_AUTH_TOKEN` | 你的 `ak-…`。它会被发成 `Authorization: Bearer`,正是这里需要的 |
| `ANTHROPIC_MODEL` | 默认主模型别名 |
| `ANTHROPIC_DEFAULT_HAIKU_MODEL` | **后台任务用的模型,必须设** |
**别用 `ANTHROPIC_API_KEY`。** 那个变量发的是 `x-api-key` 头,这里虽然也认,但 Claude Code 在交互模式下会多问你一次确认;`ANTHROPIC_AUTH_TOKEN` 立刻生效,省事。
### 为什么一定要设 haiku 那一个
Claude Code 会另外用一个 Haiku 级的小模型跑后台活:会话摘要、`/usage` 之类的命令处理。不设的话它会去请求一个这里根本没有的型号,你就会看到零星的 `MODEL_NOT_FOUND`——主对话是好的,偶尔蹦一个错。
这里目前**没有 Haiku 类别名**,所以把它指到任意一个真实存在的别名即可(上面用的是 `claude-sonnet-4.6`)。想省钱就指个便宜的,比如 `kimi-k3`。
(旧变量 `ANTHROPIC_SMALL_FAST_MODEL` 已经被官方标为废弃,新配置别再用它。)
## 可选:少一点外联
```bash
export CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC=1
```
关掉自动更新、遥测、发行说明这类非必要请求。国内网络下能少几个卡住的连接。
## 验证
```bash
claude -p "用一个词打招呼"
```
有输出就通了。想确认这一发真的走了这里:
```bash
curl "https://api.apipace.com/v1/user/statement?limit=3" -H "x-api-key: $ANTHROPIC_AUTH_TOKEN"
```
最新那条流水就是刚才那一发。控制台「调用日志」页也能看到。
## 会有哪些不一样
指向非官方地址时,Claude Code 自己会关掉一些东西,这跟这里的实现无关,但值得知道:
- **`/context` 的 token 数是估算的。** 它想调 `POST /v1/messages/count_tokens`,这里没有这个接口(404),于是退化成按字符估。不影响对话,只是那个数字不准。
- **MCP tool search 默认关闭**,Remote Control 也不可用。
- **上下文窗口可能判错**:别名不在它内置的型号清单里时,它猜不到窗口有多大。必要时用 `CLAUDE_CODE_MAX_CONTEXT_TOKENS` 显式告诉它。
## 关于 `/cost`
Claude Code 的 `/cost` 用它自己内置的价目表估算,**不是这里的扣费**。真实花费看 `GET /v1/user/statement` 或控制台「用量」页。两者对不上是正常的,以账本为准。
另外:Claude Code 是缓存最重的一类负载,而这里对话类别名冷热同价、缓存不打折。长会话的 `input_tokens` 涨得快,详见计费与账单。
## 常见问题
**`AUTH_FAILED`** —— 环境里还留着别处的 `ANTHROPIC_API_KEY`,`unset` 掉它。
**`MODEL_NOT_FOUND`,而且只是偶尔出现** —— 没设 `ANTHROPIC_DEFAULT_HAIKU_MODEL`,后台任务在打一个不存在的型号。
**`MODEL_NOT_FOUND`,每次都出现** —— `ANTHROPIC_MODEL` 填的是带日期的原始模型名。这里只认别名,`GET /v1/models` 看一眼。
**连不上 / 一直转圈** —— `ANTHROPIC_BASE_URL` 多写了 `/v1`。
---
来源:https://docs.apipace.com/docs/codex-cli
# 接入 Codex CLI
**当前版本的 Codex CLI 接不过来。** 先说结论,省你半小时。
## 为什么
Codex CLI 已经移除了对 Chat Completions 的支持,只认 OpenAI 的 **Responses API**。在配置里写 `wire_api = "chat"` 会在**加载配置时**就报错,连请求都发不出去。实测 codex-cli 0.147.0:
```
Error loading config.toml: `wire_api = "chat"` is no longer supported.
How to fix: set `wire_api = "responses"` in your provider config.
in `model_providers.apipace.wire_api`
```
而这里目前只提供 Chat Completions(`/v1/chat/completions`),没有 `/v1/responses`:
```bash
curl https://api.apipace.com/v1/responses -H "Authorization: Bearer ak-…" \
-H "content-type: application/json" -d '{"model":"claude-sonnet-4.6","input":"hi"}'
# 404 page not found
```
两边对不上。改成 `wire_api = "responses"` 也只是把报错从配置阶段推迟到请求阶段,没有开关能绕过去。
## 配置长什么样(等支持了直接抄)
Codex CLI 的自定义服务商写在 `~/.codex/config.toml` 里:
```toml
model = "claude-sonnet-4.6"
model_provider = "apipace"
[model_providers.apipace]
name = "APIPace"
base_url = "https://api.apipace.com/v1" # 带 /v1,Codex 直接在后面拼 /responses
env_key = "APIPACE_KEY" # 环境变量名,不是 key 本身
wire_api = "responses" # 目前唯一合法值,也是默认值
```
```bash
export APIPACE_KEY="ak-…"
```
`env_key` 填的是**环境变量的名字**,key 本身不落盘——这个设计是对的,照做。
## 想在终端里用编码 agent,现在能用什么
| 工具 | 能不能用 | 怎么接 |
|---|---|---|
| Claude Code | 能 | 接入 Claude Code,几个环境变量 |
| Cline(VS Code) | 能 | 接入 Cline,OpenAI 兼容或 Anthropic 两条路都行 |
| Cursor | 部分 | 接入 Cursor,只覆盖对话那一路 |
| Codex CLI | 暂不能 | 见上 |
Claude Code 是替代 Codex CLI 最接近的一个:同样跑在终端里、同样能改文件跑命令,走 Anthropic 协议,这里原生支持。
---
来源:https://docs.apipace.com/docs/cursor
# 接入 Cursor
Cursor 支持填自己的 API key(BYOK)。接过来之前,先看清楚它能用到什么程度——这比字段名重要。
## 先说限制
三条都来自 Cursor 官方文档:
- **自定义 key 只对聊天类模型生效。** Tab 补全仍然走 Cursor 自己内置的模型,不经过这里,也不花这里的钱。
- **请求仍然经 Cursor 的服务器中转**,不是从你的机器直连过来。介意这一点的话,用 Claude Code 或 Cline。
- 用自己的 key 时,Cursor 的零数据留存(ZDR)承诺不适用。
换句话说:接过来省的是对话的钱,不是订阅的钱。
## 配置
1. **Cursor Settings → Models**。
2. 在 OpenAI 那一栏填上你的 `ak-…`。
3. 打开 base URL 覆盖(OpenAI-compatible base URL override),填 `https://api.apipace.com/v1`——**带 `/v1`**,Cursor 按标准 OpenAI 客户端拼路径。
4. 在模型列表里手动添加别名(如 `claude-sonnet-4.6`),然后 **Save** / **Verify**。
**Anthropic 那一栏能不能也填自定义地址,官方文档没有记载。** 走 OpenAI 兼容这一路是确定可行的,别名照样可以填 `claude-sonnet-4.6`——协议和模型是两件事。
## 常见问题
**Verify 失败** —— 九成是 base URL 漏了 `/v1`(会拿到 `405 method not allowed`),或者模型名填的不是别名。
**开了自定义 key 之后某些功能没了** —— 见开头那三条,那些功能本来就不走这条路。
**想用 Gemini** —— 不行。`gemini-*` 只走原生 `/v1beta` 接口,任何 OpenAI 兼容客户端都调不了,见 Gemini 原生接口。
---
来源:https://docs.apipace.com/docs/cline
# 接入 Cline
Cline 是 VS Code 里的编码 agent。它没有中文界面,下面的字段名保留英文原词。
## 配置(OpenAI 兼容)
1. 侧边栏打开 Cline,点齿轮进设置。
2. **API Provider** 选 **OpenAI Compatible**。
3. 填三个字段:
| 字段 | 填什么 |
|---|---|
| Base URL | `https://api.apipace.com/v1` |
| API Key | 你的 `ak-…` |
| Model | 别名,如 `claude-sonnet-4.6` |
4. 展开下面的 **Model Configuration**,手填 **Max Output Tokens** 和 **Context Window**(Cline 不会替你猜,不填会影响截断和花费显示)。
5. 保存,开一个任务试试。
**Base URL 必须带 `/v1`。** Cline 会直接拿这个地址去拼 `/models` 和 `/chat/completions`,漏了 `/v1` 就会打到 `https://api.apipace.com/models`,拿到 404,模型列表也拉不出来。
## 配置(Anthropic 协议)
Cline 也能走 Anthropic 那一路,**规则和上面正好相反**:
1. **API Provider** 选 **Anthropic**。
2. 勾上 **Use custom base URL**。
3. 地址填 `https://api.apipace.com`——**根地址,不带 `/v1`**。Cline 把它原样交给 Anthropic SDK,SDK 自己会补 `/v1/messages`。
4. API Key 填同一把 `ak-…`。
两条路用的是同一把 key、同样的别名;选哪条看你更想要哪种协议的原生行为。
## 选支持工具调用的别名
Cline 靠工具调用改文件、跑命令。Claude 系别名(`claude-sonnet-4.6`、`claude-opus-4.6` 等)在这件事上最稳;工具调用能力弱的模型会表现为「一直在说话、不动手」。
工具调用是原样透传的,一次真实返回:
```json
{"stop_reason":"tool_use",
"content":[{"type":"tool_use","id":"toolu_01KdKPaTBcuPUDRkz62H3VaU","name":"get_weather","input":{"city":"杭州"}}]}
```
## 关于费用显示
Cline 面板上那个花费数字是它按自己填的价格算的估值,**不是这里的扣费**。真实数字看 `GET /v1/user/statement` 或控制台「用量」页。
编码 agent 的上下文越滚越长,`input_tokens` 涨得比想象的快。对话类别名冷热同价、缓存不打折,所以长任务建议中途开新会话,而不是一路滚下去。
## 常见问题
**`404` / 模型列表空的** —— OpenAI Compatible 那一路的 Base URL 漏了 `/v1`。
**`404 page not found`(Anthropic 那一路)** —— 自定义 base URL 多写了 `/v1`,去掉。
**`MODEL_NOT_FOUND`** —— Model 要填别名,不是厂商原始模型名。
**上下文超了** —— 换上下文更长的别名,或者开新任务。
---
来源:https://docs.apipace.com/docs/gemini-cli
# 接入 Gemini CLI
**Gemini CLI 目前接不过来。** 不是因为改不了地址——地址是能改的,是因为它要的接口这里只开了一小部分。
## 地址确实能改
Gemini CLI 官方支持用环境变量覆盖 base URL:
```bash
export GOOGLE_GEMINI_BASE_URL="https://api.apipace.com"
```
所以问题不在这儿。
## 卡在两处
### 一、它要 `streamGenerateContent`,这里只开了 `generateContent`
Gemini CLI 的主对话走流式,这里一律 400:
```bash
curl "https://api.apipace.com/v1beta/models/gemini-2.5-pro:streamGenerateContent" \
-H "x-api-key: ak-…" -H "content-type: application/json" \
-H "Idempotency-Key: probe-1" -d '{"contents":[{"role":"user","parts":[{"text":"hi"}]}]}'
```
```json
{"error":{"code":400,"status":"INVALID_REQUEST","execution_state":"not_started",
"message":"only generateContent is enabled","request_id":"req_01M2M84C9AJJ4BC1B7ZGSYY559"}}
```
`countTokens` 同样 400,`GET /v1beta/models` 是 404。
### 二、鉴权头对不上
Gemini CLI 把 key 发成 `x-goog-api-key`,这里只认 `Authorization: Bearer` 和 `x-api-key`:
```json
{"error":{"code":"AUTH_FAILED","message":"missing credentials: send Authorization: Bearer ak-...","request_id":"req_01M2M8AZ79E5GHY9K232D7GB0W"}}
```
再加上这里的 `/v1beta` **要求每个请求带 `Idempotency-Key`**,而 Gemini CLI 不会带。三条凑在一起,不是改配置能解决的。
## 那 Gemini 在这里怎么用
直接打原生接口,非流式、单次生成,**视频理解可用**:
```bash
curl "https://api.apipace.com/v1beta/models/gemini-2.5-pro:generateContent" \
-H "x-api-key: $APIPACE_KEY" \
-H "content-type: application/json" \
-H "Idempotency-Key: my-task-0001" \
-d '{"contents":[{"role":"user","parts":[{"text":"用一句话介绍杭州"}]}],
"generationConfig":{"maxOutputTokens":256}}'
```
完整说明、视频示例、幂等与找回规则见 Gemini 原生接口。
Google 官方的 `google-genai` SDK 也能指过来,但只有 `generate_content` 这一条路能走,而且要自己补上 `Idempotency-Key` 头。**批处理脚本可以,交互式 agent 不行。**
## 想在终端里用 agent
看 Claude Code(Anthropic 协议,原生支持)或 Cline(OpenAI 兼容)。Gemini 系列在这里适合的是批量任务:长文档理解、视频理解、一次性生成,不是聊天循环。
---
来源:https://docs.apipace.com/docs/cherry-studio
# 接入 Cherry Studio
Cherry Studio 里加一个自定义服务商,一次配好 **OpenAI 和 Anthropic 两个端点**。
## 配置
1. **设置 → 模型服务**,在服务商列表下方点 **添加服务商**。
2. 弹窗里填 **提供商名称**(随便起,比如 `APIPace`),**提供商类型**选 OpenAI。
3. **端点设置**里填地址,**API 密钥**填你的 `ak-…`:
| 字段 | 填什么 |
|---|---|
| API 地址 | `https://api.apipace.com` |
| API 密钥 | 你的 `ak-…` |
| Anthropic API 地址(可选) | `https://api.apipace.com` |
4. 点 **获取模型列表** 自动拉,或者用 `+` 手动填别名(如 `claude-sonnet-4.6`、`kimi-k3`)。
5. 回聊天界面选中模型,发一句话试试。
## 以输入框下面那行预览为准
这是 Cherry Studio 最贴心的地方:**API 地址**输入框下面会实时显示「预览」和「请求路径」。填完看一眼那一行是不是 `https://api.apipace.com/v1/chat/completions`,是就对了,不用记规则。
规则本身也不难:填**根地址**就行,Cherry Studio 会自己补 `/v1`。`https://api.apipace.com`、末尾带斜杠、甚至自己写成 `…/v1`,三种写法它都能归一到同一个地址,**不会拼出 `/v1/v1`**。想完全自己说了算,就在地址末尾加 `#`,加了之后它一个字符都不会补。
## 两个端点可以同时配
自定义服务商默认就带 OpenAI 和 Anthropic 两个端点框,两个都填 `https://api.apipace.com`(Anthropic 端点同样不用写 `/v1`)。同一把 key 在两个协议上都有效,功能上没差别——想用 Claude 的原生形状就走 Anthropic 端点,其余走 OpenAI 端点。
## 别把 Gemini 别名留在列表里
「获取模型列表」会把当前 key 可见的别名全拉进来。`gemini-*` 系列只走原生接口,在这里选中会直接报错;`gpt-image-2-official` 是异步图片任务,也不是对话模型。拉完手动删掉这两类最省事。
## 常见问题
**`405 method not allowed`** —— 看预览行,请求路径里少了 `/v1`。多半是地址末尾加了 `#` 却没把路径写全。
**`404 page not found`** —— 预览行里出现了两个 `/v1`。把地址改回根地址。
**`401` / `AUTH_FAILED`** —— key 粘贴时带了空格或换行,重新贴一次。
**模型列表拉不出来** —— 地址或 key 不对;也可能这把 key 设了模型白名单,那就只会看到白名单里的那些。
---
来源:https://docs.apipace.com/docs/chatbox
# 接入 ChatBox
ChatBox 里添加一个自定义提供方,API 模式选 **OpenAI API 兼容**。
## 配置
1. 打开 **设置 → 模型提供方**,在列表底部点 **添加** → **添加自定义提供商**。
2. 填 **名称**(随便起,比如 `APIPace`),**API 模式**选 **OpenAI API 兼容**。
3. 填这几个字段:
| 字段 | 填什么 |
|---|---|
| API 主机 | `https://api.apipace.com/v1` |
| API 路径 | `/chat/completions` |
| API 密钥 | 你的 `ak-…` |
| 模型 | 点「获取」自动拉,或「新建」手填别名 |
4. 保存,回对话窗口选中这个提供方,发一句话试试。
## `/v1` 写在「API 主机」里
ChatBox 把地址拆成 **API 主机** 和 **API 路径** 两个框,最终请求是两者相拼。它只在 **API 路径为空** 时才替你补 `/v1`——而按上面的配法路径不是空的,所以 `/v1` 必须写在主机里。
字段下面有一行**预览**显示最终 URL,填完看一眼:应该是 `https://api.apipace.com/v1/chat/completions`,**`/v1` 和 `/chat/completions` 各出现一次**。多一个少一个都不对。
## 想用 Claude 原生协议
API 模式改选 **Claude API 兼容**,API 主机填 `https://api.apipace.com/v1`。
注意方向:ChatBox 的 Claude 模式**只对官方地址自动补 `/v1`**,填自定义地址时要自己带上。这和很多客户端「Anthropic 端点不写 `/v1`」的习惯正好相反,是最容易抄错的一处。
## 模型列表里挑对话别名
「获取」会把当前 key 可见的别名全拉进来。`gemini-*` 只走原生接口、`gpt-image-2-official` 是异步图片任务,选中都会报错。只留对话别名。
## 常见问题
**`404 page not found`** —— 预览行里 `/v1` 出现了两次(主机和路径里各写了一遍)。
**`405 method not allowed`** —— 预览行里没有 `/v1`。
**回答到一半就断** —— ChatBox 的最大输出 token 设得太小。这里的超时是 300 秒总预算 / 60 秒首 token,正常对话够用。
---
来源:https://docs.apipace.com/docs/dify
# 接入 Dify
Dify 里装一个 **OpenAI-API-compatible** 模型供应商,之后所有应用(聊天助手、工作流、Agent)都能选到这里的模型。
## 配置
1. **设置 → 集成 → 模型供应商**,找到 **OpenAI-API-compatible** 并安装。
2. 在它的卡片上点 **添加模型**。
3. 填这几个字段:
| 字段 | 填什么 |
|---|---|
| 模型类型 | LLM |
| 模型名称 | 别名本身,如 `claude-sonnet-4.6` |
| API Key | 你的 `ak-…` |
| API Base URL | `https://api.apipace.com/v1` |
| 模型上下文长度 | 必填,按该模型的实际上下文填,如 `200000` |
| 最大 token 上限 | 按需,如 `8192` |
4. 保存。
**API Base URL 必须带 `/v1`**——这个字段是完整前缀,Dify 会直接在后面拼 `/chat/completions`。
## 每个别名要单独加一次
Dify 的这个供应商是 customizable-model 型的:**不会自动拉模型列表**,每个别名都得手工添一条。要用三个模型就添三次,别在「模型名称」里填一堆。
想省事的话,先想清楚这个 Dify 实例真正要用哪几个别名——通常两三个就够(一个主力、一个便宜的跑批)。
## 模型名就是别名
Dify 把「模型名称」原样发成请求里的 `model`。填错会拿到:
```json
{"error":{"code":"MODEL_NOT_FOUND","message":"unknown model \"gpt-4o\"","request_id":"req_…"}}
```
## 想用 Anthropic 协议
Dify 的 **Anthropic** 供应商也支持自定义地址,字段叫 **API URL**,填 `https://api.apipace.com`——**根地址,不带 `/v1`**,和上面的 OpenAI-API-compatible 正好相反。Dify 把它原样交给 Anthropic SDK,SDK 自己补 `/v1/messages`。
## 建议给 Dify 单开一把 key
在控制台按项目建 key,Dify 用一把、别的用别的。这样 `GET /v1/user/statement` 的 `keys[]` 能把 Dify 的花费单独拆出来,控制台用量页也能按项目看。
## 常见问题
**保存时校验失败** —— Dify 会发一次真实请求来验证。检查 API Base URL 有没有 `/v1`、模型名是不是别名、key 有没有多余空格。
**Embedding / Rerank 模型加不上** —— 这里暂不提供 embeddings(`/v1/embeddings` 返回 501)。Dify 的向量检索请另配一个 embedding 供应商。
**工作流里模型选不到** —— 添完刷新一下页面;确认添的时候「模型类型」选的是 LLM。
**上下文长度填错的后果** —— Dify 按这个数字裁历史。填大了会把超长请求发出来,模型那边直接报错;填小了会提前丢上下文。
---
来源:https://docs.apipace.com/docs/immersive-translate
# 接入沉浸式翻译
沉浸式翻译(Immersive Translate)用自定义 AI 服务接过来,网页翻译就走这里的模型。
## 配置
两条入口,选一条:
**新建一个服务**:**设置 → 翻译服务 → 添加自定义翻译服务 → 自定义AI**(在「其他 / 自定义」分组里)。
**改现有的 OpenAI 服务**:**设置 → 翻译服务 → OpenAI → 自定义 API Key → 展开更多自定义选项 👉**。
两条路要填的字段一样:
| 字段 | 填什么 |
|---|---|
| APIKEY | 你的 `ak-…` |
| 自定义 API 接口地址 | `https://api.apipace.com/v1/chat/completions` |
| 模型 | 别名,如 `kimi-k3` |
填完点「点击测试」验证,通过后保存。
## 地址填完整路径
这个字段新版本既接受 base URL 也接受完整接口地址,但**官方示例一直用的是完整路径,对所有版本都安全**。填 `https://api.apipace.com/v1/chat/completions`,别只填到 `/v1`。
## 模型要手填
它**从不自动拉模型列表**。下拉最后一项「自定义模型列表」支持一点语法:`+别名` 加一个、`-别名` 藏一个、`-all` 藏掉全部内置的。比如:
```
-all,+kimi-k3,+claude-sonnet-4.6
```
## 选便宜的别名
网页翻译是高频、小请求的负载:一篇长文会被切成几十段并发发出去。别用最贵的模型翻网页,`kimi-k3` 这类国产别名在这个场景上性价比好得多。
把插件的并发 / 每秒请求数调到这把 key 的每秒上限以内,否则会成片拿到 `RATE_LIMITED`(429)。**平台默认每 key 30 次/秒**,控制台的 API Key 页可以给这把 key 单独设更严的值。
## 建议单开一把 key
给翻译插件单独发一把 key,并在控制台给它设一个只含便宜别名的模型白名单。这样即使配置被误改成贵模型,也会直接 `PERMISSION_DENIED`,而不是安静地多花钱。
## 想用 Claude 原生协议
插件的 **Claude** 服务也支持自定义地址:**设置 → 翻译服务 → Claude → 自定义 Auth Key → 展开更多自定义选项**,把「自定义 API 接口地址」改成 `https://api.apipace.com/v1/messages`(它走的是原生 Messages 协议,不是 OpenAI 形状)。
## 常见问题
**测试不通过** —— 地址没写全(漏了 `/v1/chat/completions`),或模型名不是别名。
**翻译到一半大面积失败** —— 多半是 429。看响应里的 `Retry-After`,把并发调小。
**费用比想象的高** —— 网页翻译的请求数很多。用 `GET /v1/user/statement` 的 `models[]` 看是哪个别名在花钱。
---
来源:https://docs.apipace.com/docs/openai-sdk
# 接入 OpenAI SDK
官方 `openai` SDK 改一个 `base_url` 就能用,其余代码一行不动。
> **`base_url` 要带 `/v1`。** OpenAI SDK 不会替你补路径,填成 `https://api.apipace.com` 会打到 `/chat/completions`,拿到一个看不懂的 `405 method not allowed`。
## Python
```python
import os
from openai import OpenAI
client = OpenAI(
base_url="https://api.apipace.com/v1",
api_key=os.environ["APIPACE_KEY"],
)
r = client.chat.completions.create(
model="claude-sonnet-4.6",
max_tokens=16,
messages=[{"role": "user", "content": "用一个词打招呼"}],
)
print(r.choices[0].message.content)
```
```
你好!👋
```
`model` 填别名,见 快速开始;Claude、Kimi、MiniMax 这些别名在这个协议上都能用,只有 `gemini-*` 和图片别名不行。
## 读平台字段
`request_id` 和 `billable_units` 是标准 OpenAI 形状之外的两个字段,SDK 把它们放在 `model_extra` 里:
```python
print(r.model_extra["request_id"]) # req_01M2M7K25B9BB9GM07EGJWKD6R
print(r.model_extra["billable_units"]) # {'input_tokens': 16, 'output_tokens': 9, 'usage_source': 'upstream'}
```
`billable_units` 是这一笔按多少 token 计的费;扣了多少钱拿 `request_id` 去查 `GET /v1/requests/{id}`,见计费与账单。
## 流式
计费信息在流的最后一帧:一个 `choices` 为空、带 `billable_units` 的 chunk。SDK 会正常把它当 chunk 交给你,判一下就行:
```python
units = None
with client.chat.completions.create(
model="claude-sonnet-4.6", max_tokens=16, stream=True,
messages=[{"role": "user", "content": "用一个词打招呼"}],
) as stream:
for chunk in stream:
extra = chunk.model_extra or {}
if "billable_units" in extra:
units = extra["billable_units"]
elif chunk.choices and chunk.choices[0].delta.content:
print(chunk.choices[0].delta.content, end="", flush=True)
print(units) # {'input_tokens': 16, 'output_tokens': 11, 'usage_source': 'upstream'}
```
不想读也没关系——不处理它就是了,空 `choices` 的 chunk 不会破坏任何标准解析逻辑。
## 幂等与关联编号
两个可选的头,SDK 用 `extra_headers` 传:
```python
r = client.chat.completions.create(
model="claude-sonnet-4.6",
max_tokens=16,
messages=[{"role": "user", "content": "用一个词打招呼"}],
extra_headers={
"Idempotency-Key": "job-42", # 7 天内同键重放返回首发结果,不重复扣费
"X-Request-ID": "job-42", # 只是标签,之后可用它找回这一笔
},
)
```
## 常见问题
**`MODEL_NOT_FOUND`** —— `model` 填的是厂商原始模型名。这里只认别名,用 `client.models.list()` 看一眼。
**`405 method not allowed`** —— `base_url` 漏了 `/v1`。
**用了 Azure 的客户端类** —— `AzureOpenAI` 走的是另一套路径形状,请用普通的 `OpenAI`。
**要 Responses API** —— 目前只提供 Chat Completions(`/v1/chat/completions`)。
---
来源:https://docs.apipace.com/docs/anthropic-sdk
# 接入 Anthropic SDK
官方 `anthropic` SDK 改一个 `base_url` 就能用。
> **`base_url` 不带 `/v1`。** Anthropic SDK 自己会补 `/v1/messages`,填成 `https://api.apipace.com/v1` 就变成 `/v1/v1/messages`,返回 `404 page not found`。这一点和 OpenAI SDK 正好相反。
## Python
```python
import os
import anthropic
client = anthropic.Anthropic(
base_url="https://api.apipace.com",
api_key=os.environ["APIPACE_KEY"],
)
msg = client.messages.create(
model="claude-sonnet-4.6",
max_tokens=16,
messages=[{"role": "user", "content": "用一个词打招呼"}],
)
print(msg.content[0].text)
```
```
你好!👋
```
SDK 会把 key 发成 `x-api-key`,平台照收。`tools`、`system`、`thinking`、图片输入这些原生能力都原样透传。
非 Claude 的别名(`kimi-k3`、`minimax-m3`)在这个协议上一样能用——这就是双协议的意义:换模型不用换 SDK。
## 读平台字段
```python
print(msg.model_extra["request_id"]) # req_01M2M7KGJ8B9GFRD30CB23HKMR
print(msg.model_extra["billable_units"]) # {'input_tokens': 16, 'output_tokens': 9, 'usage_source': 'upstream'}
```
`usage` 里的 `cache_creation_input_tokens` 和 `cache_read_input_tokens` **恒为 0**:客户面冷热同价,缓存不单独计价,全部输入 token 都折进 `billable_units.input_tokens`。这不是 bug,见计费与账单。
## 流式
```python
with client.messages.stream(
model="claude-sonnet-4.6", max_tokens=16,
messages=[{"role": "user", "content": "用一个词打招呼"}],
) as stream:
for text in stream.text_stream:
print(text, end="", flush=True)
```
流的最后有一个平台追加的自定义事件 `event: asterapi_billing`,SDK 不认识它、会安静跳过,`text_stream` 和 `get_final_message()` 都照常工作。想读这一帧就自己解析 SSE,`data` 是 `{"request_id", "billable_units"}`。
## 幂等与关联编号
```python
msg = client.messages.create(
model="claude-sonnet-4.6",
max_tokens=16,
messages=[{"role": "user", "content": "用一个词打招呼"}],
extra_headers={"Idempotency-Key": "job-42", "X-Request-ID": "job-42"},
)
```
## 常见问题
**`404 page not found`** —— `base_url` 多写了 `/v1`,去掉它。
**`AUTH_FAILED`** —— 不显式传 `api_key=` 时,SDK 会去读环境变量 `ANTHROPIC_API_KEY`;机器上如果存着别处的 key,发出去的就是那一把。像上面那样把 key 显式传进构造函数最省事。
**`MODEL_NOT_FOUND`** —— `model` 要填别名(`claude-sonnet-4.6`),不是 `claude-sonnet-4-6-20260514` 这种带日期的原始名。
---
来源:https://docs.apipace.com/docs/images
# 图片生成
生成图片走一套独立的**异步任务**接口:提交拿任务号,轮询等结果,结果 URL 24 小时内有效。
别名 `gpt-image-2-official`。它不是对话模型,**不能填进 `/v1/chat/completions` 或 `/v1/messages`**。
## 为什么是异步的
一张图片要几秒到几十秒,同步接口在这个时间尺度上不可靠:连接断了你就不知道钱扣没扣、图出没出。所以这里把「接单」和「取货」分开:
- `POST /v1/image-tasks` 落库接单,返回任务号和预占金额,**202**。这一步是原子的:任务、冻结的价格、预占的资金要么都在,要么都不在。
- `GET /v1/image-tasks/{task_id}` 轮询状态和结果,**免费**,余额为零也能读。
- `GET /v1/image-tasks/by-client/{client_request_id}` 用你自己的编号找回——接单响应丢了也能拿回任务,而且**不会重新生成一张**。
## 提交
```bash
curl https://api.apipace.com/v1/image-tasks \
-H "x-api-key: $APIPACE_KEY" \
-H "content-type: application/json" \
-H "Idempotency-Key: docs-img-20260916-a" \
-d '{
"client_request_id": "docs-img-20260916-a",
"submit_not_after": "2026-09-16T04:16:51Z",
"model": "gpt-image-2-official",
"prompt": "一只橘猫坐在窗台上晒太阳,水彩风格",
"size": "1:1",
"resolution": "1k",
"quality": "low",
"n": 1
}'
```
```json
{
"request_id": "req_01M2M6SF2M9ZNXTK1CR7R1F32R",
"task_id": "img_01M2M6SF2VG5NWRXQW48DPC4A4",
"status": "accepted",
"billing": {"status":"held","reserved_micro_cny":101785,"sales_micro_cny":0,"currency":"CNY"},
"hold_expires_at": "2026-09-16T04:49:53.535047Z",
"retry_after": 5
}
```
### 字段
| 字段 | 必填 | 说明 |
|---|---|---|
| `client_request_id` | 是 | 你自己生成的唯一编号,1–128 字符。**`Idempotency-Key` 头必须填成同一个值** |
| `submit_not_after` | 是 | 接单截止时间(RFC 3339),必须在**未来 3 分钟以内**。超出返回 `INVALID_SUBMIT_DEADLINE` |
| `model` | 是 | `gpt-image-2-official` |
| `prompt` | 是 | 1–64000 字符 |
| `size` | 是 | `auto` `1:1` `3:2` `2:3` `4:3` `3:4` `5:4` `4:5` `16:9` `9:16` `2:1` `1:2` `21:9` `9:21` |
| `resolution` | 是 | `1k` `2k` `4k`。**`4k` 只支持 `16:9` `9:16` `2:1` `1:2` `21:9` `9:21`** |
| `quality` | 是 | `low` `medium` `high` |
| `n` | 是 | 恒为 `1`,一次只出一张 |
| `image_urls` | 否 | 参考图,最多 4 张。可以是 `https://` URL,也可以是 `data:image/png;base64,…`(png / jpeg / webp,单张解码后 ≤ 1 MiB)。整个请求体 ≤ 8 MiB |
`submit_not_after` 是给你自己上的保险:网络抖动导致请求晚到时,过了这个点就不会再开一张你已经不想要的图。
## 轮询
```bash
curl https://api.apipace.com/v1/image-tasks/img_01M2M6SF2VG5NWRXQW48DPC4A4 \
-H "x-api-key: $APIPACE_KEY"
```
```json
{
"request_id": "req_01M2M6T40PJWYGQA2827XQBP73",
"task_id": "img_01M2M6SF2VG5NWRXQW48DPC4A4",
"status": "succeeded",
"billing": {"status":"charged","sales_micro_cny":41965,"currency":"CNY"},
"hold_expires_at": "2026-09-16T04:49:53.535047Z",
"images": [{"url":"https://…/image/9998210467891166-ea292e00-…","expires_at":1789618508}],
"retry_after": 5
}
```
按响应里的 `retry_after` 秒数轮询就行(上面这张 1K / low 的图,提交后第 12 秒变 `succeeded`)。
| `status` | 含义 |
|---|---|
| `accepted` | 已接单,还没开始 |
| `dispatching` / `running` | 正在生成 |
| `succeeded` | 出图了,看 `images[]` |
| `failed` | 失败,看 `error_code`;预占已释放,不扣钱 |
| `unknown` | 结果暂时确认不了。**不要重新提交一个新编号**,继续按 `retry_after` 轮询原任务 |
`unknown` 是这套接口最值得理解的一个状态:它表示「这单可能已经在生成了」。此时新开一单等于付两份钱,所以平台宁可让你等,也不会替你重试。超过 `hold_expires_at` 预占会自动释放,迟到的成功结果不再向你追扣。
## 用自己的编号找回
接单响应在网络里丢了?拿你提交时那个 `client_request_id` 查:
```bash
curl https://api.apipace.com/v1/image-tasks/by-client/docs-img-20260916-a \
-H "x-api-key: $APIPACE_KEY"
```
返回的就是原任务,查询不会创建也不会重新生成。
也可以直接重放提交请求:**`Idempotency-Key` 与请求体都完全相同**时返回 202 + 原任务(不会再生成一张,也不会再扣一次);编号相同但请求体变了(哪怕只是 `submit_not_after` 换了个时间),返回 409 `IDEMPOTENCY_CONFLICT`。所以重放要原样重放。
## 结果有效期
`images[].expires_at` 是 Unix 秒。实测一张 04:15 出的图,`expires_at` 是次日 04:15——**大约 24 小时**。过期后 URL 就取不到图了。
**请及时把图转存到你自己的存储里。** 这个 URL 是临时的,不要写进数据库当长期地址,也不要直接发给最终用户。
## 计费
图片按**五个桶**分别计价,不是按张收固定价格:
| 桶 | 是什么 |
|---|---|
| 文本输入 | 你的 `prompt` |
| 缓存文本输入 | 命中缓存的那部分文本输入,单价更低 |
| 图片输入 | 参考图 |
| 缓存图片输入 | 命中缓存的那部分图片输入,单价更低 |
| 图片输出 | 生成的图本身。分辨率、质量、比例都会改变它 |
五个桶的单价在 `GET /v1/pricing` 的 `image_models[].tariff` 里,免鉴权:
```json
{"id":"gpt-image-2-official","display_name":"GPT Image 2 Official",
"capabilities":["image_generation"],
"tariff":{"version":"openai-gpt-image-2-standard-2026-09-14",
"text_input_micro_usd_per_m":5000000,
"cached_text_input_micro_usd_per_m":1250000,
"image_input_micro_usd_per_m":8000000,
"cached_image_input_micro_usd_per_m":2000000,
"image_output_micro_usd_per_m":30000000}}
```
单位是**微美元 / 百万 token**(`5000000` = $5 / M),结算时按平台汇率折成人民币微元。人看的版本在 。
这是对话接口之外**唯一**会因为缓存而便宜的地方:对话类别名冷热同价,图片不是。
几条规矩:
- 接单时按规格价 + 有界的输入预算算一个**预占上限**(上例 `reserved_micro_cny` 101,785 = ¥0.101785),最终按实际用量结算(上例 `sales_micro_cny` 41,965 = ¥0.041965)。任务接下之后这个上限就不变了,**不会透支**。
- 只有成功且没超过冻结期限的图才扣款。失败、释放、用量确认不了,都不扣。
- 用量缺失或无法拆分到五个桶时,平台不猜价:任务判失败、释放预占、也不会给你一张「免费的成功图」。
- 迟到的证据不会事后追加扣款。
想核对某一单,拿接单响应里的 `request_id` 去 `GET /v1/requests/{id}`;账户级汇总在 `GET /v1/user/statement` 的 `models[]` 里,图片单独计在 `images` 计数上。
## 错误码
图片任务有自己的一套错误码(比对话接口的 14 个更细),信封形状一样,但 `message` 就是 `code` 本身,请直接判 `code`:
| code | HTTP | 什么情况 |
|---|---|---|
| `INVALID_IMAGE_REQUEST` | 400 | 请求体解析不了或字段缺失 |
| `INVALID_IMAGE_SPEC` | 400 | `size` / `resolution` / `quality` 组合非法(常见:4K 配了不支持的比例) |
| `INVALID_IDEMPOTENCY_KEY` | 400 | `Idempotency-Key` 缺失或与 `client_request_id` 不一致 |
| `INVALID_SUBMIT_DEADLINE` | 400 | `submit_not_after` 不在未来 3 分钟以内 |
| `INVALID_REFERENCE_IMAGE` | 400 | 参考图不是 png / jpeg / webp,或超过 1 MiB,或 URL 非法 |
| `TOO_MANY_REFERENCE_IMAGES` | 400 | 超过 4 张 |
| `MODEL_NOT_ALLOWED` | 403 | 这个别名不在 key 的白名单里 |
| `IMAGE_TASK_NOT_FOUND` | 404 | 本 key 下没有这个任务 |
| `IDEMPOTENCY_CONFLICT` | 409 | 同一个编号,请求体变了 |
| `SUBMISSION_EXPIRED` | 410 | 过了 `submit_not_after` 才到 |
| `IMAGE_BODY_TOO_LARGE` | 413 | 请求体超过 8 MiB |
| `IMAGE_CAPACITY_BUSY` | 429 | 并发接单槽位满了,稍后重试 |
| `IMAGE_PRICE_UNAVAILABLE` / `IMAGE_ROUTE_UNAVAILABLE` / `IMAGE_PRICE_OR_ROUTE_UNAVAILABLE` | 503 | 这个规格当前没有可用价目或通道 |
| `IMAGE_SERVICE_UNAVAILABLE` | 500 | 平台内部错误 |
任务失败时 `error_code` 里还会出现这几个(都已释放预占、不扣钱):`IMAGE_NOT_STARTED`、`IMAGE_PROVIDER_REJECTED`、`IMAGE_GENERATION_FAILED`、`IMAGE_RESULT_INVALID`、`IMAGE_USAGE_UNCONFIRMED`;`status` 为 `unknown` 时通常伴随 `IMAGE_RESULT_UNCONFIRMED` 或 `IMAGE_STATUS_UNAVAILABLE`。
余额不足按通用口径返回 `INSUFFICIENT_BALANCE`(402),见限制与错误码。
## 一段能跑的轮询代码
```python
import time, requests
BASE = "https://api.apipace.com"
H = {"x-api-key": KEY, "content-type": "application/json"}
cid = "job-2026-09-16-0001" # 你自己的唯一编号,重试时必须复用
r = requests.post(f"{BASE}/v1/image-tasks",
headers={**H, "Idempotency-Key": cid},
json={
"client_request_id": cid,
"submit_not_after": time.strftime("%Y-%m-%dT%H:%M:%SZ", time.gmtime(time.time() + 120)),
"model": "gpt-image-2-official",
"prompt": "一只橘猫坐在窗台上晒太阳,水彩风格",
"size": "1:1", "resolution": "1k", "quality": "low", "n": 1,
})
r.raise_for_status()
task = r.json()
while task["status"] not in ("succeeded", "failed"):
time.sleep(task.get("retry_after", 5))
task = requests.get(f"{BASE}/v1/image-tasks/{task['task_id']}", headers=H).json()
if task["status"] == "failed":
raise RuntimeError(task.get("error_code"))
url = task["images"][0]["url"] # 24 小时内有效,立刻转存
print(url, task["billing"]["sales_micro_cny"] / 1e6, "CNY")
```
---
来源:https://docs.apipace.com/docs/gemini-native
# Gemini 原生接口
Gemini 系列走 Google 自己的原生形状,路径 `POST /v1beta/models/{别名}:generateContent`。视频理解就在这里。
Gemini 别名**不能**填进 `/v1/chat/completions` 或 `/v1/messages`——那样会拿到:
```json
{"error":{"code":"INVALID_REQUEST","message":"this endpoint requires Gemini non-streaming contents","request_id":"req_01M2M7ERGYAKQ5VHZTJ104RH4J"}}
```
## 别名
| 别名 | 说明 |
|---|---|
| `gemini-3.1-pro-preview` | 当前主力 |
| `gemini-2.5-pro` | 上一代 Pro |
| `gemini-3-pro-preview` | 兼容别名,实际返回 3.1 Pro |
## 最短的一次调用
```bash
curl "https://api.apipace.com/v1beta/models/gemini-2.5-pro:generateContent" \
-H "x-api-key: $APIPACE_KEY" \
-H "content-type: application/json" \
-H "Idempotency-Key: docs-gemini-20260916-b" \
-d '{
"contents": [{"role":"user","parts":[{"text":"用一句话介绍杭州"}]}],
"generationConfig": {"maxOutputTokens": 256}
}'
```
```json
{
"candidates": [{
"content": {"role":"model","parts":[{"text":"杭州,一座浸润在西…"}]},
"finishReason": "MAX_TOKENS"
}],
"modelVersion": "gemini-2.5-pro",
"responseId": "qheqapWYGo2x_9MP25uM6As",
"usageMetadata": {
"promptTokenCount": 5,
"candidatesTokenCount": 7,
"thoughtsTokenCount": 245,
"totalTokenCount": 257
}
}
```
返回是原生 Gemini 形状,**没有额外的平台字段**——平台信息全在响应头里(见下)。
> `thoughtsTokenCount` 是思考 token,它按输出计费。上面那次只输出 7 个可见 token,却花了 245 个思考 token;`maxOutputTokens` 给小了会像第一次那样直接 `MAX_TOKENS` 截断,而思考 token 已经产生。**给 Gemini Pro 留够 `maxOutputTokens`。**
## `Idempotency-Key` 是必填的
这是这个接口和其它接口最不一样的地方:**没有 `Idempotency-Key` 直接 400**。
```json
{"error":{"code":400,"status":"INVALID_REQUEST","execution_state":"not_started",
"message":"a stable Idempotency-Key of at most 128 characters is required",
"request_id":"req_01M2M7ETJP0BDQCVVTAZ7JPB9N"}}
```
原因是这些请求可能很贵(一段视频轻易就是几十万 token),而网络会断。平台用这个键保证:**同一个键 + 同样的正文,最多只会真的生成一次**。
- 同键同正文重放 → 返回原结果,响应头带 `x-p34-replayed: true`,不再扣一次钱。
- 同键但正文变了 → 冲突,拒绝。
- 键用过了就不会因为超时或过期而重新开放,**不存在「换个时间重试同一个键会再买一次」**。
所以这个键要**稳定**:按你业务里那个任务的 ID 生成,别用随机数,也别每次重试换一个。
## 四个响应头
| 头 | 值 | 怎么用 |
|---|---|---|
| `x-p34-execution-state` | `not_started` / `completed` / `unknown` | 见下 |
| `x-p34-usage-state` | `reported` / `unknown` | `unknown` = 用量没拿到,这一单**不扣钱** |
| `x-p34-charged-micro-cny` | 整数微元 | 这一单扣了多少 |
| `x-p34-replayed` | `true` | 这次返回来自重放,不是新生成 |
`x-p34-execution-state` 是断线之后决定「能不能重来」的唯一依据:
- `not_started`:请求根本没发出去,**可以**换个新键重来。
- `completed`:已经跑完了。
- `unknown`:可能跑了也可能没跑。**不要新建调用**,拿原来的键去查(见下一节)。
## 结果找回
拿你提交时用的那个 `Idempotency-Key` 去查——**注意路径里填的是这个键,不是 `request_id`**:
```bash
curl "https://api.apipace.com/v1beta/invocations/docs-video-20260916-a" \
-H "x-api-key: $APIPACE_KEY"
```
返回原生成结果,响应头带 `x-p34-replayed: true`。这个查询不发起生成、不扣费、不要求余额,同租户同 key 才能读。
返回 409 表示:还在跑、结果确认不了、或者正文超过 1 MiB 没法重放。**409 本身不表示可以新建调用。**
## 视频理解
视频用原生的 `inline_data` 传,`mime_type` 写视频的真实类型:
```bash
python3 - <<'PY' > body.json
import base64, json
v = base64.b64encode(open("clip.mp4","rb").read()).decode()
json.dump({"contents":[{"role":"user","parts":[
{"inline_data":{"mime_type":"video/mp4","data":v}},
{"text":"这段视频里画面的颜色先后是什么?只答颜色。"}]}],
"generationConfig":{"maxOutputTokens":512}}, open("/dev/stdout","w"))
PY
curl "https://api.apipace.com/v1beta/models/gemini-2.5-pro:generateContent" \
-H "x-api-key: $APIPACE_KEY" -H "content-type: application/json" \
-H "Idempotency-Key: clip-2026-09-16-0001" \
--data-binary @body.json
```
返回里 `promptTokensDetails` 会按模态拆开,视频占了多少一目了然:
```json
{
"candidates": [{"content":{"role":"model","parts":[{"text":"红色"}]},"finishReason":"STOP"}],
"modelVersion": "gemini-2.5-pro",
"usageMetadata": {
"promptTokenCount": 271,
"promptTokensDetails": [{"modality":"TEXT","tokenCount":13},{"modality":"VIDEO","tokenCount":258}],
"candidatesTokenCount": 1,
"thoughtsTokenCount": 405,
"totalTokenCount": 677
}
}
```
上面这一发是一段 1 秒、128×128 的测试片,视频部分 258 token,整单扣 30,791 微元 = ¥0.030791(思考 token 是大头)。**真实素材的 token 数大致随时长线性增长**,先用一小段试出单价再批量跑。
## 限制
| 项 | 限制 |
|---|---|
| 请求体 | ≤ 96 MiB。没有 Files API,大文件要么压,要么切段 |
| 输出 | 只有文本、单候选 |
| 不支持 | `tools`、显式上下文缓存、Files、流式 |
| 长上下文 | prompt 超过 200,000 token 走长上下文档价目 |
| 预占 | 带视频的请求按模型最大输入量(1,048,576 token)加 `maxOutputTokens` 预占,**最终按实际用量结算**。所以余额要够预占,而不是够实际花费 |
## 计费
按 `usageMetadata` 里的实际用量结算:`promptTokenCount` 计输入,`candidatesTokenCount` + `thoughtsTokenCount` 计输出。缓存命中的部分也一并折进输入。
**用量拿不到时(`x-p34-usage-state: unknown`)结果照给、不扣钱**,平台不按媒体字节数猜 token。这类调用会计进 `GET /v1/user/statement` 的 `unconfirmed_calls`,之后也不会偷偷追扣。
单价见 ,或 `GET /v1/pricing`(免鉴权)里 `capabilities` 含 `gemini_native` 的那几条。
## 错误信封
这个接口用的是 Google 原生形状,和 `/v1` 的信封**不一样**:
```json
{"error":{"code":400,"status":"INVALID_REQUEST","execution_state":"not_started",
"message":"…","request_id":"req_…"}}
```
`code` 是 HTTP 数字,`status` 才是字符串码。多一个 `execution_state`,语义同响应头。5xx 表示执行结果未确认——**只查原调用,不要自动再买一次**。
---
来源:https://docs.apipace.com/docs/billing
# 计费与账单
钱怎么算、去哪儿查、怎么逐笔对上账。一句话口径:按 token 计费,人民币微元整数结算,每一笔都能拿请求号查回原始数字。
## 口径
### 按别名的挂牌价计费
每个别名有两个价:输入一个价、输出一个价,按每百万 token 算。人看的价目表在 ;程序读这一份,**免鉴权**:
```bash
curl https://api.apipace.com/v1/pricing
```
```json
{
"currency": "CNY",
"unit": "micro_yuan_per_million_tokens",
"book_version": 13,
"effective_at": "2026-09-16T04:55:30.258040Z",
"models": [
{"id":"claude-sonnet-4.6","display_name":"Claude Sonnet 4.6",
"capabilities":["chat","stream","tools"],
"input_per_m":26250000,"output_per_m":105000000},
{"id":"kimi-k3","display_name":"Kimi K3",
"capabilities":["chat","stream","tools"],
"input_per_m":20000000,"output_per_m":100000000}
],
"image_models": [
{"id":"gpt-image-2-official","display_name":"GPT Image 2 Official",
"capabilities":["image_generation"],
"tariff":{"version":"openai-gpt-image-2-standard-2026-09-14",
"text_input_micro_usd_per_m":5000000,
"cached_text_input_micro_usd_per_m":1250000,
"image_input_micro_usd_per_m":8000000,
"cached_image_input_micro_usd_per_m":2000000,
"image_output_micro_usd_per_m":30000000}}
]
}
```
金额是**整数微元 / 百万 token**:`26250000` 就是 ¥26.25 / M。缓存 60 秒,`book_version` 变了就说明价目簿换版了。
`models[]` 是文字模型,只有输入、输出两个价(缓存不单独计价,见下)。`image_models[]` 是图片,按五个 token 桶计价,桶单价以美元牌价给出(`5000000` 微美元 = $5 / M),结算时按平台汇率折成人民币——见图片生成。
这里给的是**牌价**:账户上如果有单独的折扣,不体现在这个接口里。
### 缓存不单独计价
对话类别名**冷热同价**:不管这次请求命中了多少提示词缓存,你看到的价格和扣费都一样。响应体 `usage` 里的 `cache_creation_input_tokens` / `cache_read_input_tokens` 恒为 0,`billable_units.input_tokens` 是全部输入 token 加在一起。
这意味着你不用为了省钱去改 prompt 结构,也不会因为缓存失效被突然多收一笔;代价是缓存命中率很高的负载(比如长期跑同一份 system prompt 的编码 agent)省不到缓存的钱。
> 图片任务是唯一的例外:它按五个桶分别计价,缓存过的输入确实更便宜。见图片生成。
### 每笔请求只有两个计费数
都在响应体的 `billable_units` 里:
| 字段 | 含义 |
|---|---|
| `input_tokens` | 全部输入 token:新鲜的、读缓存的、写缓存的加在一起,按输入价计 |
| `output_tokens` | 输出 token,按输出价计。推理型模型的思考 token 算在这里 |
| `usage_source` | 这两个数字从哪来,见下 |
```
扣费 = input_tokens × 输入单价 + output_tokens × 输出单价
```
整数微元结算,1 元 = 1,000,000 微元。
举个可以逐位核算的例子。`kimi-k3` 挂牌 ¥20 / M 输入、¥100 / M 输出,一次 87 输入 + 16 输出的请求:
```
87 × 20 + 16 × 100 = 1,740 + 1,600 = 3,340 微元 = ¥0.003340
```
`GET /v1/requests/{id}` 返回的 `sales_amount` 就是 3340。
### usage_source
| 值 | 含义 |
|---|---|
| `upstream` | 模型服务方在响应里报的数字,绝大多数请求都是这个 |
| `provider_bill` | 从服务方账单里取的数字 |
| `local-estimated` | 服务方没报用量,平台本地估算。它是可辨认的,方便你对账时区别对待 |
### 流式请求的计费帧
流式响应里 token 数要等流结束才知道,所以平台在流的最后追加一帧:
Anthropic 协议在 `message_stop` 之后追加一个自定义事件:
```
event: message_stop
data: {"type":"message_stop"}
event: asterapi_billing
data: {"request_id":"req_01M2M6PG4852YZTT01CK0XRF3D","billable_units":{"input_tokens":16,"output_tokens":9,"usage_source":"upstream"}}
```
OpenAI 协议在最后一个 chunk 之后、`[DONE]` 之前追加一个 `choices` 为空数组的 chunk:
```
data: {"id":"req_01M2M6PDJD01S07FTQKRP0G5XV","object":"chat.completion.chunk","created":1789531994,"model":"claude-sonnet-4.6","choices":[],"billable_units":{"input_tokens":16,"output_tokens":9,"usage_source":"upstream"}}
data: [DONE]
```
标准 SDK 会忽略自己不认识的事件和空 `choices` 的 chunk,不影响正常解析。要读这一帧的话,认 `billable_units` 字段即可。
### 预占与结算
请求开始时按输入估算与 `max_tokens` 预占一笔余额(`held`),结束后按实际用量结算、释放预占。
```
可用余额 = 余额 − 预占 + 授信
```
预占不够会直接返回 `INSUFFICIENT_BALANCE`(402),不会把请求发出去。返空、模型服务方失败、被拒绝的请求不计费。所以余额充足时 `max_tokens` 设大一点没有额外成本,只是会多占一会儿;余额紧张时 `max_tokens` 设得太大会让请求提前被 402 挡住。
## 查账的四个接口
### 查余额
```bash
curl https://api.apipace.com/v1/user/balance -H "x-api-key: $APIPACE_KEY"
```
```json
{
"balance_micro_cny": 188634760,
"held_micro_cny": 0,
"available_micro_cny": 188634760,
"credit_limit_micro_cny": 0,
"currency": "CNY",
"checked_at": "2026-09-16T04:12:27.751462416Z",
"request_id": "req_01M2M6N0Q62NA2MN0VDWRY2AG5"
}
```
四个金额都是整数微元,除以 1,000,000 是元:上面是 ¥188.63。查询本身不扣费、不占预占,余额为零也能查。同一账户的多把 key 读到的是同一个钱包。
### 查单笔扣费
```bash
curl https://api.apipace.com/v1/requests/req_01M2M6NZBQRN748G5NXAMRF6W1 \
-H "x-api-key: $APIPACE_KEY"
```
返回这一笔的 token、`sales_amount`(微元)、延迟拆分和事后修正:
```json
{
"request_id": "req_01M2M6NZBQRN748G5NXAMRF6W1",
"status": "FINALIZED",
"model": "claude-sonnet-4.6",
"stream": false,
"usage": {"input_tokens":16,"output_tokens":9,"total_tokens":25},
"billable_units": {"input_tokens":16,"output_tokens":9,"request_count":1,"usage_source":"upstream"},
"sales_amount": 1365,
"currency": "CNY",
"route_id": "01M2M6NZC9C8HYDJFE0ZAFEP4R",
"latency_ms": {"total":1288,"upstream_first_byte":1274,"upstream_total":1274,"platform_overhead":14},
"created_at": "2026-09-16T04:12:59.134049Z",
"adjustments": []
}
```
`sales_amount` 是当时的扣费,**永不改写**。如果这笔后来被退款或补扣,会以 `adjustments[]` 追加一条,正数是退回给你的:
```
钱包净变化 = sales_amount − Σ(adjustments 里为正的退款)
```
`latency_ms.platform_overhead` 是总耗时减去模型服务方那一段,也就是平台自己花掉的毫秒数。只能查本账户的请求,别人的请求和不存在的请求同样返回 404。
### 按你自己的编号找回
发请求时带上 `X-Request-ID`,响应会原样回给你一个 `X-Client-Request-Id` 头;之后就算 `request_id` 丢了,也能用自己的编号找回这一笔:
```bash
curl https://api.apipace.com/v1/messages \
-H "x-api-key: $APIPACE_KEY" -H "X-Request-ID: my-job-42" \
-H "anthropic-version: 2023-06-01" -H "content-type: application/json" \
-d '{"model":"kimi-k3","max_tokens":16,"messages":[{"role":"user","content":"say hi"}]}'
curl https://api.apipace.com/v1/requests/by-client/my-job-42 -H "x-api-key: $APIPACE_KEY"
```
返回的是和按请求号查一模一样的那张单子。编号缺失或在本账户下不唯一都返回 404。**这个查询不会让 POST 变成幂等的**——要幂等请用 `Idempotency-Key`,见限制与错误码。
### 全账户对账单
```bash
curl "https://api.apipace.com/v1/user/statement?limit=50" -H "x-api-key: $APIPACE_KEY"
```
同一个快照里读钱包和全历史账本,一次性给出四组东西:
| 组 | 字段 | 说明 |
|---|---|---|
| 钱包 | `balance_micro_cny` `held_micro_cny` `available_micro_cny` `credit_limit_micro_cny` | 和 `/v1/user/balance` 同一个数 |
| 汇总 | `funding_micro_cny` `adjustments_micro_cny` `charges_micro_cny` `refunds_micro_cny` `net_spent_micro_cny` | 充值、调整、扣费、退款、净消费 |
| 自检 | `reconciliation_difference_micro_cny` `held_difference_micro_cny` | 两个都是 0 表示账本和钱包对得上 |
| 明细 | `keys[]` `models[]` `entries[]` | 按 key、按别名的消费,以及逐条流水 |
恒等式是给你核算用的:
```
balance + net_spent = funding + adjustments
```
流水条目的 `entry_type` 有 `TOPUP`(充值)、`RESERVE`(预占)、`CAPTURE`(扣款)、`RELEASE`(释放预占)、`REFUND`、`ADJUSTMENT`、`COMPENSATION`。一次普通请求会留下 `RESERVE` → `CAPTURE` + `RELEASE` 三条:
```json
{"id":"01M2M6PH894MMSP6X2PJRNDRXH","entry_type":"CAPTURE","request_id":"req_01M2M6PG4852YZTT01CK0XRF3D",
"model":"claude-sonnet-4.6","key_id":"01M1FDD9Z6ERRMVSH40WSGQSTY",
"balance_delta_micro_cny":-1365,"held_delta_micro_cny":-1365,"created_at":"2026-09-16T04:13:17.448955Z"}
```
流水按时间和编号倒序分页,用返回的 `next_cursor` 翻下一页(`?cursor=…`)。同账户的多把 key 共用一个钱包,所以 `keys[]` 里只分摊消费,**不会按 key 重复累计充值和余额**。查询免费,余额耗尽也能读。
`unconfirmed_calls` 是结果或用量还待核查的调用数——这类调用不会按估算扣你的钱,也不会事后偷偷追扣。
## 充值
目前用兑换码:拿到码之后在控制台「钱包」页兑换,立刻到账并在流水里留一条 `TOPUP`。
## 汇总用量
按天 / 按小时、按项目 / 应用 / 别名分组的用量与花费,在控制台「用量」页看。控制台还能建 key、设模型与 IP 白名单、看钱包流水和调用日志。
---
来源:https://docs.apipace.com/docs/limits
# 限制与错误码
一页看完所有会挡住你的东西:约定、超时、限流、以及 14 个错误码分别该怎么处理。
## 约定
| 项 | 约定 |
|---|---|
| 幂等 | 带 `Idempotency-Key` 头的请求,7 天内同键重放返回首发结果、不重复扣费;同键仍在进行中返回 `REQUEST_IN_PROGRESS`(409,带 `Retry-After`)。图片任务和 Gemini 原生接口**必须**带这个头 |
| 关联编号 | 带 `X-Request-ID` 头(≤ 64 字符),响应回 `X-Client-Request-Id`,之后可用 `GET /v1/requests/by-client/{id}` 找回这一笔。它只是个标签,**不产生幂等** |
| 超时 | 单次请求总预算 300 秒,首 token 60 秒;超过返回 `UPSTREAM_TIMEOUT`(504) |
| 断开 | 客户端中途断开会取消模型服务方那一侧的调用,已产生的用量照常结算 |
| 白名单 | key 可以限定可用别名和来源 IP,越界返回 `PERMISSION_DENIED`(403);不在白名单里的别名在 `/v1/models` 里也看不到 |
| 追踪 | 每个响应带 `X-Request-Id`(同响应体 `request_id`)和 `X-Route-Id`。出问题时把这两个值一起报过来 |
| 隐私 | 请求与响应正文默认不留存 |
## 频率限制
每把 key 有自己的每秒请求数上限(一秒固定窗口)。**平台默认每 key 30 次/秒**;在控制台的 API Key 页可以给某把 key 设更严的 `rps_limit`(1 到平台默认之间),留空就用默认。
**每一个被限流管着的响应都带用量头**,不只是被拒的那个——好让你在被拒之前就慢下来:
```
HTTP/1.1 200 OK
X-RateLimit-Limit: 1
X-RateLimit-Remaining: 0
```
超了返回 429,多一个 `Retry-After`:
```
HTTP/1.1 429 Too Many Requests
Retry-After: 1
X-RateLimit-Limit: 1
X-RateLimit-Remaining: 0
```
```json
{"error":{"code":"RATE_LIMITED","message":"rate limit exceeded, retry shortly","request_id":"req_01M2M96HPG0DWFMKZQ5HN9JT9P"}}
```
窗口就是一秒宽,所以 `Retry-After` 永远是 `1`——等一秒再发,别退避成指数,也别立刻重试。
| 头 | 含义 |
|---|---|
| `X-RateLimit-Limit` | 这把 key 当前生效的每秒上限 |
| `X-RateLimit-Remaining` | 这一秒还剩多少次 |
| `Retry-After` | 等几秒再试,恒为 `1` |
被限流的请求**根本没发出去,不扣钱**。
另外两种 429 不是频率问题,重试策略不同:
- `BUDGET_EXCEEDED`:账户的日 / 月预算用完了,重试没有意义,去控制台调预算或充值。
- `MODEL_RATE_LIMITED`:这个别名当前拿不到配额,带 `Retry-After` 时照它退避重试通常能过。
## 服务状态
怀疑是平台的问题而不是你的代码时,先看 `GET /status`。**免鉴权、故障时也能读**:
```bash
curl https://api.apipace.com/status
```
```json
{
"window_minutes": 15,
"updated_at": "2026-09-16T04:55:06.073713Z",
"models": [
{"id":"claude-sonnet-4.6","requests":128,"upstream_error_rate_bp":0,"p50_latency_ms":1840},
{"id":"kimi-k3","requests":12,"upstream_error_rate_bp":833,"p50_latency_ms":940}
],
"overall": {"requests":140,"upstream_error_rate_bp":71}
}
```
最近 15 分钟的对话别名健康度,30 秒更新一次(`Cache-Control: public, max-age=30`)。
`upstream_error_rate_bp` 是基点:**833 = 8.33%**。它只统计平台该负责的失败——模型服务方报错、超时、限流,以及平台内部错误;参数写错、鉴权失败、余额不足这类由你造成的 4xx 计进 `requests` 但**不**计进错误率,所以这个数字不会因为你自己调错而变难看。`p50_latency_ms` 是端到端总耗时的中位数。
## 错误信封
所有错误一个形状,四百到五百全都一样:
```json
{"error":{"code":"AUTH_FAILED","message":"missing credentials: send Authorization: Bearer ak-...","request_id":"req_01M2M6Q5AE31PQTE9AJHGRJPVD"}}
```
`message` 是给人看的说明,不含服务方原文、凭据或任何供应商身份。程序请判 `code`,不要判 `message`。
## 14 个错误码
这 14 个码是冻结的,不会悄悄增删。
| code | HTTP | 什么情况 | 怎么办 |
|---|---|---|---|
| `INVALID_REQUEST` | 400 | 参数或请求体不合法 | 改请求,重试无用 |
| `AUTH_FAILED` | 401 | key 缺失、无效、已禁用或过期 | 检查 `Authorization` / `x-api-key` 是否带上、是否被截断 |
| `INSUFFICIENT_BALANCE` | 402 | 可用余额不够预占 | 充值,或把 `max_tokens` 调小 |
| `PERMISSION_DENIED` | 403 | 别名或来源 IP 不在这把 key 的白名单里 | 去控制台改白名单 |
| `MODEL_NOT_FOUND` | 404 | 别名不存在,或对这把 key 不可见 | 用 `GET /v1/models` 核对拼写 |
| `NOT_FOUND` | 404 | 资源不存在,包括查别人的 `request_id` | 核对编号和账户 |
| `REQUEST_IN_PROGRESS` | 409 | 同一个 `Idempotency-Key` 还在进行中 | 按 `Retry-After` 等一会儿再查 |
| `CONTENT_BLOCKED` | 422 | 安全拦截 | 改内容,重试无用 |
| `BUDGET_EXCEEDED` | 429 | 账户日 / 月预算用完 | 去控制台调预算 |
| `RATE_LIMITED` | 429 | 这把 key 的每秒请求数超限 | 按 `Retry-After` 退避 |
| `MODEL_RATE_LIMITED` | 429 | 这个别名当前拿不到配额 | 按 `Retry-After` 退避,或换个别名 |
| `UPSTREAM_ERROR` | 502 | 模型服务方返回失败(已脱敏) | 可重试;反复出现请带 `X-Request-Id` 和 `X-Route-Id` 找我们 |
| `UPSTREAM_TIMEOUT` | 504 | 超过 300 秒总预算或 60 秒首 token | 缩短输入、或改用流式 |
| `INTERNAL_ERROR` | 500 | 平台内部错误 | 带上两个追踪号找我们 |
哪些会扣钱:**402 / 403 / 404 / 429 一律不扣**(请求根本没发出去);502 / 504 不扣;200 按实际用量扣。
## 几个容易踩的点
**响应里没有钱。** 对话接口的响应体只有 token,`sales_amount` 在 `GET /v1/requests/{id}` 里。这是有意的:扣费以账本为准,不以响应体为准。
**`model` 填的是别名。** 填厂商原始模型名(`gpt-4o`、`claude-3-5-sonnet-20241022` 这种)会直接 404:
```json
{"error":{"code":"MODEL_NOT_FOUND","message":"unknown model \"gpt-4o\"","request_id":"req_01M2M6Q6N5W1R2J26QB7RGVKX3"}}
```
**Gemini 系列别名只认原生协议。** 拿 `gemini-*` 去打 `/v1/chat/completions` 会被拒。见Gemini 原生接口。
**图片不是对话接口。** `gpt-image-2-official` 走 `POST /v1/image-tasks` 的异步任务,不能填进 `messages` 请求里。见图片生成。
---
来源:https://docs.apipace.com/docs/faq
# 常见问题
按「连不上 / 账号和充值 / 安全 / 能做什么 / 花了多少」分五组。找不到答案就带上 `X-Request-Id` 和 `X-Route-Id` 找我们。
## 连接
**Base URL 到底填哪个?带不带 `/v1`?**
看客户端自己会不会补路径。粗略的规律是「OpenAI 那一栏带 `/v1`,Anthropic 那一栏不带」,但**每个客户端都有自己的脾气**,各篇接入指南里写了确切写法:
| 客户端 | 填什么 |
|---|---|
| OpenAI SDK、Cline、Dify、Cursor | `https://api.apipace.com/v1` |
| Anthropic SDK、Claude Code、Cline 的 Anthropic 那一路、Dify 的 Anthropic 那一路 | `https://api.apipace.com` |
| Cherry Studio | `https://api.apipace.com`(它自己补,带不带都归一到同一个地址) |
| ChatBox | 主机 `https://api.apipace.com/v1` + 路径 `/chat/completions` |
| 沉浸式翻译 | 完整地址 `https://api.apipace.com/v1/chat/completions` |
填错的症状:多了 `/v1` 会 `404 page not found`;少了 `/v1` 会 `405 method not allowed`。两个都不是鉴权问题,别去翻 key。Cherry Studio 和 ChatBox 的输入框下面都有一行实时预览,**以那一行显示的最终 URL 为准**比背规则可靠。
**哪些接不了?** Codex CLI(只认 Responses API)和 Gemini CLI(要流式原生接口和 `x-goog-api-key`),原因和替代方案见 接入 Codex CLI、接入 Gemini CLI。
**为什么填了别名还是 `MODEL_NOT_FOUND`?**
三种可能:拼错了;填的是厂商原始模型名而不是别名;这把 key 设了模型白名单,这个别名不在里面。`GET /v1/models` 返回的就是这把 key 真正能用的全集,以它为准。
**`gemini-*` 为什么在对话接口上报 400?**
Gemini 系列只走原生 `/v1beta` 接口,见 Gemini 原生接口。有些客户端会把 `/v1/models` 里的别名全部拉进下拉框,选到 Gemini 就会报错——手动只填对话别名即可。
**能用中转站的「试一下」在页面里直接发请求吗?**
可以,API 参考右侧填 key 就能发一次真实请求,会真的扣钱(几厘)。
**连接超时 / 很慢?**
单次请求总预算 300 秒、首 token 60 秒。长输出请开流式,`stream: true` 之后首 token 通常一两秒就到。如果是整体慢而不是某个模型慢,`curl https://api.apipace.com/status` 看一眼最近 15 分钟各别名的错误率和 p50 延迟——免鉴权,故障时也能读。
**同一把 key 能在几台机器上同时用吗?**
能。key 上可以设 IP 白名单,不设就不限来源。要分开统计的话在控制台按项目 / 应用各建一把,用量和花费会分开归集。
## 账号与充值
**怎么注册?**
去 :填邮箱 → 收 6 位验证码 → 设密码(至少 8 位)→ 勾选同意《服务条款》和《隐私政策》。提交后直接登录,租户和默认项目 / 应用都会自动建好。
不勾同意会被挡下:
```json
{"error":{"code":"INVALID_REQUEST","message":"请先阅读并同意《服务条款》和《隐私政策》","request_id":"req_…"}}
```
**一定要邀请码吗?**
不用。有邀请码可以在注册页「有邀请码?点这里填写」里填上(填了就会被核销),没有也能注册。
**收不到验证码怎么办?**
按顺序排查:
1. **先看垃圾邮件**,验证码信最常掉在那儿。
2. **60 秒之内不能重发。**太快点会拿到 429,响应头 `Retry-After: 60`:
```json
{"error":{"code":"RATE_LIMITED","message":"验证码刚刚发过,请稍后再试","request_id":"req_…"}}
```
3. **验证码 10 分钟过期、只能用一次、最多试 5 次。**过期或试错太多次就重新发一次,别拿旧码反复试。
4. 确认邮箱地址没打错——重置密码时,对一个**没有注册过**的邮箱同样返回成功但不会发信(这是故意的,不让人拿它试探哪些邮箱注册过)。
**验证码发不出去了 / 提示次数用完**
有三层配额:同一个邮箱每小时 5 次、同一个网络每小时 20 次,整个登录注册接口每个来源每分钟 60 次请求。踩到哪一层,`message` 会说是邮箱还是网络,`Retry-After` 会告诉你等多久。等就是了——刷新重试只会把配额耗得更快。
**忘记密码?**
,邮箱 + 验证码 + 新密码。注意:**重置会作废这个账号已有的全部登录**,其它设备都要重新登录。这是有意的——会去重置密码的人通常是怀疑账号被别人登着,留着那个人的会话就白重置了。
**登录提示「尝试次数过多」**
同一个邮箱或同一个来源 15 分钟内失败 10 次就会被锁一会儿,返回 429 并带 `Retry-After`。等它过去,或者直接去重置密码。
**怎么充值?**
目前用兑换码:拿到码后在控制台「钱包」页兑换,立刻到账,流水里留一条 `TOPUP`。
**余额能退吗?**
充值余额只用于本平台调用,不支持提现。
**key 丢了怎么办?**
key 创建时只显示一次,丢了就在控制台把它禁用或轮换,再建一把。轮换有一小时的宽限期,老 key 在这段时间里还能用,方便你分批换配置。
**一个账户能建几把 key?**
不限。多把 key **共用同一个钱包**——`GET /v1/user/statement` 的 `keys[]` 会把消费分摊到每把 key 上,但余额和充值只算一次,不会重复累计。
## 安全
**你们会存我的对话内容吗?**
请求与响应正文默认不留存。落库的是元数据:请求号、别名、token 数、扣费、延迟、状态码。
**key 在你们那边怎么存的?**
只存哈希,明文只在创建时返回给你那一次。
**能限制一把 key 只能用某些模型 / 只能从公司 IP 调用吗?**
能,控制台的 API Key 页可以设模型白名单和 IP 白名单,越界返回 `PERMISSION_DENIED`(403)。白名单之外的别名在 `/v1/models` 里也不会出现。
**预算能卡住吗?**
能,账户有日 / 月预算,超了返回 `BUDGET_EXCEEDED`(429)。
## 功能
**有哪些模型?**
Claude 全系、GPT-5.4 与 5.4-mini、Gemini Pro 系(只走原生接口)、Kimi、MiniMax、DeepSeek、Qwen、GLM,外加一个图片模型。别名和单价以 `GET /v1/pricing` 实时返回为准,别照着这段话记——上下架和调价都不会提前通知这一页。
```bash
curl https://api.apipace.com/v1/pricing # 免鉴权,全部在售别名 + 单价
curl "https://api.apipace.com/v1/models?include=all" -H "x-api-key: ak-…" # 这把 key 能用的
```
**支持流式吗?**
两个协议都支持。流的最后会多一帧计费信息,标准 SDK 会忽略它。见计费与账单。
**支持工具调用 / function calling 吗?**
支持,原样透传。Anthropic 协议的一次真实返回:
```json
{"stop_reason":"tool_use",
"content":[{"type":"tool_use","id":"toolu_01KdKPaTBcuPUDRkz62H3VaU","name":"get_weather","input":{"city":"杭州"}}]}
```
**支持图片输入(视觉)吗?**
支持,按各协议的原生形状传即可。视频要用 Gemini 原生接口。
**支持 embeddings 吗?**
暂不支持,`/v1/embeddings` 会返回 501。
**支持 OpenAI Responses API 吗?**
暂不支持,只有 Chat Completions。所以像 Codex CLI 这种可以选协议的客户端,要把协议选成 chat。
**能生成图片吗?**
能,走异步任务接口,见图片生成。
**有 Webhook 吗?**
暂无,图片任务请轮询。
**有 SLA 吗?**
目前没有正式的可用性承诺。
## 花费与账单
**响应里为什么没有价格?**
有意为之:扣费以账本为准,不以响应体为准。响应里给的是 token(`billable_units`),钱拿 `request_id` 去 `GET /v1/requests/{id}` 查。
**为什么 `cache_read_input_tokens` 永远是 0?**
对话类别名冷热同价,缓存不单独计价,全部输入 token 都折进一个输入价。好处是价格可预测;代价是缓存重的负载省不到缓存的钱。图片任务是唯一按缓存分桶计价的地方。
**Claude Code 的 `/cost` 和你们的账单对不上?**
对不上是正常的。Claude Code 用它自己内置的价目表估算,不知道这里的挂牌价。以 `GET /v1/user/statement` 或控制台「用量」页为准。
**扣费怎么精确到分?**
不精确到分——精确到**微元**(1 元 = 1,000,000 微元),整数结算,永不四舍五入到分。一次 16 输入 + 9 输出的 `claude-sonnet-4.6` 请求扣 1,365 微元 = ¥0.001365。
**失败的请求扣钱吗?**
402 / 403 / 404 / 429 不扣(请求根本没发出去),502 / 504 不扣。只有真正产生了用量才扣。
**为什么余额突然少了一块,过一会儿又回来了?**
那是预占(`held`)。请求开始时按输入估算和 `max_tokens` 冻结一笔,结束后按实际用量结算、释放剩下的。`GET /v1/user/balance` 的 `available_micro_cny` 才是你真正能用的数。
**怎么按项目 / 按应用分账?**
在控制台建项目和应用,各自发 key。用量页可以按项目 / 应用 / 别名分组看,`GET /v1/user/statement` 也会按 key 和别名拆开。
**价目在哪看?**
。机器读的那份是 `GET /v1/pricing`,免鉴权、缓存 60 秒,见计费与账单。