← 回首页

开发文档

高级用法与 API 参考

给自己写程序的人:每个请求头和响应头的含义、怎样控制输出上限与调度、生图和视频接口的全部参数,以及计费的精确口径。

最后更新
2026-10-14

请求头

三套协议端点(/v1/chat/completions、/v1/messages、/v1/responses)都认下面这些头。名字大小写不敏感。除了 Authorization,其余都是可选的偏好:越界的值会被夹到合法范围,不会报错。

请求头取值作用
AuthorizationBearer ap_live_…必填。所有 /v1/* 端点都用它,见快速接入的「认证」
X-AGIPlan-Difficulty0 ~ 1 的小数覆盖这一次请求的难度判断。只影响 auto、auto-fast(决定它的质量下限)和自定义模型挑组;按真名点模型时不起作用
X-AGIPlan-First-Byte-Timeout-Ms毫秒,夹到 5,000 ~ 上限首字节等多久就放弃这条线、换下一条(首字节之前换线不会让你收到半截回答)。上限随输入变长:60 秒起,每 5 万输入 token 多 15 秒,最多 180 秒
X-AGIPlan-Sceneweb / agent / batch / chat告诉调度这次请求是什么场景:web 盯着屏幕等第一个字,优先快;agent 是编码代理,优先稳、质量容差最小;batch 没人在等,优先省;chat 均衡。不传就按请求自动判断(是否流式、带几个工具、对话轮数、客户端标识);认不得的值忽略。影响 auto 选哪个模型,以及同一个模型的几条线路之间怎么取舍。和密钥的调度偏好叠加:场景先定基础取舍,密钥偏好(速度 / 成本 / 缓存优先)在它上面做有限的偏移,偏好是「自动」时不变
X-AGIPlan-Strict-Max-Tokens1 / true / yes / on要求严格的输出上限:只调度到会遵守 max_tokens 的线路,能力里带 loose_max_tokens 的线路不会被选中。详见下面「输出上限」
anthropic-version如 2023-06-01/v1/messages 照官方 SDK 发即可
anthropic-beta逗号分隔按白名单转发给 Claude 线路;不在白名单里的会被去掉,并写进响应头 x-agiplan-dropped-params(形如 anthropic-beta:名字)

响应头

三套文本协议端点(/v1/chat/completions、/v1/messages、/v1/responses)的成功响应带下面这些头;被拒的响应没有追踪号和实际模型(这次没跑),但照带三个额度头;429 另带 retry-after(规则见下表)。生图端点成功时只带 x-agiplan-trace、x-agiplan-model-actual、x-agiplan-cu 和(换过线时)x-agiplan-failover,不带额度头和 x-agiplan-billed-group。**视频端点不带任何 x-agiplan-* 头:报障请给任务号 id,这次收了多少看任务对象的 cu。排查问题时请附上 x-agiplan-trace**,用它可以调出这次调用的完整调度链路(快速接入的「溯源」一节)。

响应头例子含义
x-agiplan-tracetr_9f3c…这次调用的追踪号
x-agiplan-model-actualgemini-3.8-flash实际服务这次请求的模型。用 auto、自定义模型或发生能力换线时,它可能和你填的不同
x-agiplan-model-requestedgemini-3.8-flash只在点名的模型被换了时出现:你点名的那个模型(实际是谁看上一行)。见「能力标记」一节
x-agiplan-model-swapmissing:tools和上一个头一起出现:点名的模型缺哪项能力,所以被换
x-agiplan-billed-groupfast按哪个能力组的额度计费
x-agiplan-failovertrue首字节之前换过线路。只在发生时出现
x-agiplan-quota-session / -week / -monthremaining=72%; resets=2026-10-11T08:00:00.000Z三个额度窗口的剩余比例和重置时间。429 时同样带上,方便你决定退避多久
x-agiplan-dropped-paramstemperature,content[].image_url被丢弃或降级的参数。我们不静默吞参数,丢了什么都写在这里
x-agiplan-max-tokens-default4096你没传 max_tokens,我们补的值。这个值决定预扣多少额度,也会真的发给模型
x-agiplan-cu51.462生图接口:这一次收了多少 CU
retry-after30429 时建议等待的秒数。三套文本协议、生图、视频五个入口同一规则:某个额度窗口挡住时是到它重置的秒数;并发满时是 2;说不出何时恢复的 429 不带。生成结果链接限次时固定 60

输出上限(max_tokens)

  • 不传就补 4096,并在响应头 x-agiplan-max-tokens-default 里说明。想要更长的回答请显式传 max_tokens(Responses 协议是 max_output_tokens)。
  • Responses 协议不传 max_output_tokens 时不补 4096(会把推理模型的思考预算一起卡死),按声明了 64000 处理:输出按 16000 预扣,发给模型的上限是「预扣那部分 + 单次允许超出的那部分」,长回答照样写得完,但输出不再没有上限。
  • 预扣按上限算,结算按实际用量。 请求开始时按「输入 + max_tokens」的最坏情况占住额度,结束后按模型实际报告的用量结算,多退少补。传一个远大于需要的上限只会在请求进行中多占额度,不会多收钱。
  • 有些线路的上游不遵守 max_tokens:模型可能输出比上限更多的内容,结束原因仍是正常结束。这些线路在 /v1/models 的 capabilities 里带 loose_max_tokens,控制台「模型与价格」里标为「上限不严格」。默认照常调度,超出的部分按实际用量计费。
  • 需要严格上限时(按 token 控制成本、程序依赖截断位置、批量任务),请求里加 X-AGIPlan-Strict-Max-Tokens: 1:调度会跳过 loose_max_tokens 的线路,用 auto 或能力组名调用时会改用能遵守上限的线路。按真名点了一个只有这类线路的模型、或者往上找遍能力组也没有能遵守上限的线路时,返回 400 strict_max_tokens_unavailable,不会悄悄换模型——重试不会改变结果,去掉这个头或换个模型 / 能力组。
curl https://agiplan.dev/v1/chat/completions \
  -H "Authorization: Bearer $AGIPLAN_KEY" \
  -H "X-AGIPlan-Strict-Max-Tokens: 1" \
  -H "Content-Type: application/json" \
  -d '{"model":"auto","max_tokens":200,"messages":[{"role":"user","content":"用三句话概括这段代码"}]}'
要求严格输出上限

模型能力标记

GET /v1/models 的每个模型带 capabilities 数组。调度按它做准入,不是参考:请求需要某项能力(例如带了 tools)而线路没有,那条线路就不会被选中;按真名点了一个没有该能力的模型时,网关不让请求失败,而是换一个有这项能力的模型、按它计费。被换了一定看得到:响应头 x-agiplan-model-actual(实际)、x-agiplan-model-requested(点名的)、x-agiplan-model-swap(缺什么);响应体顶层多一个 agiplan 对象(model_requested、model_actual、missing_capabilities、notice)——非流式在响应体里,流式在第一帧(Chat Completions 的第一个 chunk、Messages 的 message_start.message、Responses 的 response.created.response),模型输出的正文里不插任何字;控制台「用量明细」里那一行标着「点名 X → 实际 Y(X 不支持 …)」,可以用「只看被换模型」筛出来;同一把密钥 24 小时内第一次被换时,控制台「通知」里会有一条站内说明(不发邮件)。每个模型不支持 tools 时会改用谁,写在「模型与价格」页那个模型的说明里。要固定用点名的模型,请求里就别带它不支持的能力。

标记含义
tools支持工具调用(function calling)。Codex、Claude Code 这类编码代理必需
vision能看图:OpenAI 的 image_url、Anthropic 的 image 块、Responses 的 input_image 都会被转换过去
json支持 JSON 模式 / 结构化输出(response_format)
long长上下文
thinking可开启深度思考
responses原生支持 Responses 协议,Codex 的特有条目原样透传。只有历史里带 compaction / web_search_call / local_shell_call 这类条目的请求才要求它;apply_patch、namespace 工具和 include 不要求,点名 Claude 照样跑 Claude
image生图模型,用 /v1/images/generations 和 /v1/images/edits
video视频模型,用 /v1/videos
quality:<值>生图线路认的 quality 取值(如 quality:high)。请求的 quality 不在其中的线路不会被选中
loose_max_tokens上游不保证遵守 max_tokens,见上一节
thinking_forced思考关不掉:不管请求里要不要思考都会先思考,思考消耗的 token 算在输出里。max_tokens 给得太小(低于 1024)时 auto 和能力组不会派给它;按真名点它时请把输出上限留宽

生图:/v1/images/generations 与 /v1/images/edits

请求体与 OpenAI 一致。edits 用 multipart 上传原图(image 或 image[],最多 16 张)和可选的 mask,每张(含 mask)不超过 10 MB,其余参数相同。

参数说明
model不传默认 gpt-image-2。生图模型名,见 /v1/models 里 kind: "image" 的条目。写模型名:这个模型的所有线路从便宜到贵依次尝试,按实际出图那条线收费。写某条线的名字(模型条目里的 pinnable,如 gpt-image-2-vip、nano-banana-2-cl):只走那一条,按它的价收
prompt必填
size不传默认 1024x1024。宽x高,例如 1024x1024、2048x1152。按长边分档:≤1024 是 1K,≤2048 是 2K,≤4096 是 4K,价格按档收。部分模型只出得了某些档,选了出不了的档会返回 size_unavailable
n不传默认 1,取值 1 ~ 4。按实际出图张数收费:4 张里成功 3 张就收 3 张
qualityauto / low / medium / high,部分模型还有 xhigh / max。模型支持哪些看它的 quality:* 能力标记。这个模型出得了这个尺寸的线路都不认你传的值时,返回 400 quality_unavailable,错误信息里列出可选值
response_format不传或 b64_json:返回 base64(默认,和 OpenAI 一致)。url:返回我们自己域名的链接 https://agiplan.dev/v1/media/<id>,保存 7 天
  • 响应体形如 {created, data:[{b64_json}], output_format, size, quality}。output_format 会如实写 png / jpeg / webp——不同模型出的格式不同,按它决定文件扩展名,不要一律存成 .png。
  • 生图失败(内容审核没通过、上游故障、超时)不计费。审核类失败返回 400 upstream_rejected,换一条线路通常也会被拒,请改写提示词。生成一旦发出无法中止:客户端中途断开时上游通常仍会完成生成,完成了就按实际张数计费(我们照付上游,2026-10-12 起与流式对话同一口径)。
  • 价格:/v1/models 里生图模型的 pricing.per_image 按 1k / 2k / 4k 给出 cu(起价,最便宜那条线)和 cu_max(最贵那条线),以及按量折算的人民币;pinnable 列出每条可锁定的线和它的价。
  • 参考图:/v1/images/edits 带的原图不另收费,按输出张数计价,和出图一样。
  • edits 的常见错误码:invalid_multipart(400,不是 multipart/form-data)、missing_image(400,没带原图)、too_many_images(400,超过 16 张)、image_too_large(413,单张超过 10 MB)。

视频:/v1/videos(异步任务)

一条视频要一到几分钟,所以视频是异步任务:提交立刻返回任务号,之后轮询进度,完成后取片。计费只在出片成功时发生。

端点说明
POST /v1/videos提交任务,返回 202 和任务对象
GET /v1/videos/{id}查进度。建议每 3 ~ 5 秒查一次;查询本身会推动任务前进,频繁查询不会多收钱
GET /v1/videos/{id}/content取成片(mp4),需要密钥,支持 Range(拖进度条)
GET /v1/videos列出这把密钥所属账户最近 50 个任务
DELETE /v1/videos/{id}删除已结束的任务和成片,要 chat:write 作用域。进行中的任务不能删(409),因为上游已经开始生成
参数说明
model不传默认 minimax-h3。视频模型名。和生图一样按线计价:写模型名从便宜的线路开始,写 pinnable 里的线名只走那一条
prompt必填,最多 4,000 字。按分镜写效果最好:时长、风格、逐段镜头(带时间码)、对白、声音设计、负面提示
resolution480p / 768p / 1080p,以模型在 /v1/models 里的 pricing.per_second 为准。不传取这个模型最低的那一档
seconds整数,不传默认 5。480p / 768p 最长 15 秒,1080p 最长 10 秒(也接受 duration)
aspect_ratio16:9(横,默认)或 9:16(竖)
images可选,参考图,最多 9 张。http(s) 链接或 data:image/…;base64,…。base64 的素材合计不超过 8 MB,更大的用链接或素材库
audios可选,参考音频(音色、配乐),最多 3 段,格式同上(和 images 的 base64 合计算)
assets可选,素材库里的素材 id(ast_…)。和 images / audios 一起算张数
seed可选,整数。其他参数不变时结果更接近上一次
import time, requests

H = {"Authorization": "Bearer ap_live_你的密钥"}
job = requests.post("https://agiplan.dev/v1/videos", headers=H, json={
    "model": "minimax-h3",
    "prompt": "视频时长:6秒|高端产品广告|微距摄影……",
    "resolution": "768p", "seconds": 6, "aspect_ratio": "16:9",
}).json()

while job["status"] in ("queued", "in_progress"):
    time.sleep(4)
    job = requests.get(f"https://agiplan.dev/v1/videos/{job['id']}", headers=H).json()

if job["status"] == "completed":
    print(job["url"], job["cu"])   # url 是我们域名的链接,7 天内有效
else:
    print(job["error"])            # 失败不计费
提交与轮询(Python)
  • 任务对象字段:id、status(queued → in_progress → completed / failed)、progress(0 ~ 100)、model、resolution、seconds、aspect_ratio、cu、created_at、completed_at、url、expires_at、error、retries。
  • 自动重试:上游在生成途中失败或长时间没有进展时,系统可能自动切换线路重新生成,最多 2 次。这时任务号不变、status 仍是 in_progress、progress 从 0 重新开始,retries 是已经重试的次数;计费不变,仍然只在出片成功时收一次。内容审核没通过、请求里直接带了参考素材(images / audios)的任务不会自动重试;只用素材库素材(assets)的可以。
  • 计费:提交时按「每秒价 × 秒数」预扣,出片后正式计费;失败、内容审核没通过、超时(25 分钟没出片)都不收,预扣全额退回。进行中的任务占一个并发名额。
  • 常见错误码:invalid_resolution、invalid_duration、invalid_aspect_ratio、too_many_images、too_many_audios、invalid_asset、invalid_seed、prompt_too_long(参数问题,400);resolution_unavailable(503,此刻没有线路出得了这个分辨率,换一档或稍后);video_not_found(404,任务不存在或不是你的);video_not_ready(409,还没出片就取片);video_in_progress(409,删除进行中的任务);assets_too_large(413,base64 素材合计超限)、too_many_asset_bytes(400,引用的素材合计超限);content_rejected(审核没通过)、generation_failed(上游生成失败,可直接重试)、timeout、upstream_lost(写在任务的 error 里)。
  • 成片保存 7 天,到期自动删除。需要长期保留请自行下载。

素材库:/v1/assets(参考素材上传一次、反复引用)

素材库需要有效套餐(个人或所在组织的,含企业定制套餐),或开启按量续用并有余额。发送和存储都按 CU 计、没有免费额度,和其他调用一样从套餐额度里扣(见下面「收费」)。参考图、参考音频先存进素材库,生成视频时只传素材 id。文件直传对象存储、不经过我们的网关,所以不受请求体大小限制;同一个文件只存一份,下次直接引用。控制台「在线视频」加的素材也存在这里,两边是同一个库。

端点说明
POST /v1/assets登记要上传的文件,返回素材对象和一次性的上传地址 upload。同一个文件(按 sha256)已经在库里就直接返回那一条,upload 为 null,不用再传
PUT <upload.url>把文件本体原样 PUT 过去,必须带上 upload.headers 里的每个头(内容类型写进了签名);文件大小也写进了签名,正文字节数必须等于登记时的 bytes,否则存储直接拒(403)。地址 15 分钟内有效,不用带密钥
POST /v1/assets/{id}/confirm上传完确认。我们核对大小和文件头,通过后 status 变 ready、可以引用;重复确认没有副作用
GET /v1/assets列素材(按最近使用排序,每页 60,?kind=image|audio、?offset=),附带 usage(已用字节、个数、上限、冻结状态、两样的 CU 单价、现在每天的存储费、本月已扣)
GET /v1/assets/{id}查一个素材
DELETE /v1/assets/{id}删除,立即生效。引用它、还没出片的视频任务可能因此失败(失败不收费)
登记参数说明
kindimage 或 audio
mime图片:image/png、image/jpeg、image/webp(不收 SVG);音频:audio/mpeg、audio/wav、audio/mp4、audio/m4a、audio/aac、audio/ogg
bytes文件字节数。图片不超过 20 MB,音频不超过 50 MB;传上来的比登记的大会被删掉
sha256文件内容的 SHA-256(64 位小写十六进制),用来去重
name可选,文件名,方便你在控制台认出它
import hashlib, requests

H = {"Authorization": "Bearer ap_live_你的密钥"}
data = open("product.png", "rb").read()

a = requests.post("https://agiplan.dev/v1/assets", headers=H, json={
    "kind": "image", "mime": "image/png", "bytes": len(data),
    "sha256": hashlib.sha256(data).hexdigest(), "name": "product.png",
}).json()
if a["upload"]:                      # 库里已经有同一个文件时是 None
    requests.put(a["upload"]["url"], headers=a["upload"]["headers"], data=data).raise_for_status()
    a = requests.post(f"https://agiplan.dev/v1/assets/{a['id']}/confirm", headers=H).json()

job = requests.post("https://agiplan.dev/v1/videos", headers=H, json={
    "model": "minimax-h3", "prompt": "<Picture 1> 的产品在白色转台上 360° 缓慢旋转……",
    "resolution": "768p", "seconds": 6, "aspect_ratio": "16:9",
    "assets": [a["id"]],
}).json()
上传一张参考图并用来生成视频(Python)
  • 引用:/v1/videos 的 assets 填素材 id,可以和 images / audios 混用,张数合在一起算(图最多 9、音频最多 3);一次生成引用的素材合计不超过 100 MB。顺序:images 在前、assets 里的图按给的顺序排在后面,提示词里的 <Picture N> 按这个顺序数。
  • 保留:30 天没被引用的素材自动删除,每引用一次重新计时。登记了但 60 分钟内没确认的作废。
  • 上限:最多存 200 GB、500 个,每天最多登记 300 次。满了先删再传。
  • 收费(按 CU,没有免费额度):两样各记一条用量,在控制台用量明细里单独列出,模型标识是 asset-transfer(素材发送)和 asset-storage(素材存储)。① 发送:每次生成(包括失败后自动换线重试)把引用的素材库素材发给模型一次,约 1053 CU / GB,提交时收——生成失败时视频不收、发送照收,提交没成的不收。② 存储:在库的素材每天按当时的量扣一次,约 8.3 CU / GB / 天。都从这次调用的付费方扣:套餐额度,用完或没有套餐时按按量续用从余额扣(密钥要允许按量)。发送扣不动时这次提交整单被拒(quota_exceeded 429 / no_subscription 403,消息里写明是素材发送)。直接在请求里带的素材不经过素材库,不收。
  • 存储费扣不动时:素材库暂停引用、暂停上传(asset_frozen / asset_library_frozen,403),额度恢复或充值后下一轮扣费即恢复(定时任务一小时一轮),扣不动的那几天不补扣。连续 7 天扣不动,全部删除(从最久没用的开始)。
  • 自动重试:只用素材库素材的视频任务,生成途中上游失败时可以换线重新生成(我们重新签发素材链接);直接在请求里带 images / audios 的不会。
  • 常见错误码:asset_not_found(404,素材不存在、已删除或不是你的);asset_size_mismatch(400,确认时实际字节数和登记的不一致,重新上传);asset_check_unavailable(503,暂时没法核对文件内容,稍后再确认一次);asset_library_requires_plan_or_balance(403,既没有有效套餐,也没开按量续用或没有余额);invalid_asset_type、invalid_asset(400);asset_too_large(413);asset_quota_exceeded、asset_count_exceeded(400,库满);asset_upload_rate(429);asset_not_uploaded、asset_bad_content(确认时:还没传完 / 文件内容和类型对不上);asset_intent_expired(410,重新登记);invalid_asset_ref(引用了不存在、已删除或不是你的素材)。

计费的精确口径

  • 文本:按模型实际报告的输入、输出、缓存读、缓存写四类 token 分别计价,系数见「模型与价格」。每条线路有自己的价,调度落到哪条按哪条收,x-agiplan-model-actual 告诉你是哪个模型。所以 /v1/models 文本模型的 pricing 和「模型与价格」页上标「当前最低」的价,是此刻可用线路里最便宜那一条的系数(熔断、排空的线不算,随线路状态实时变);实际这一笔可能更高,以用量明细为准。一条可用线路都没有时给的是登记价。
  • 模型报告的用量明显不对时按实际产出计:模型报告的输出 token 远多于实际交给你的内容、而且快到不可能(按整次耗时折算每秒上千 token)时,输出按实际产出的内容计——响应里的 usage(流式是最后一帧)给的也是这个数,和计费一致;用量明细的链路会写明模型原本报了多少。看不见的推理(只回结论、推理过程不流出的模型)不受影响:它们报的多,但速度正常。
  • 流式中途断开:已经产出的部分照常计费。断开后我们会读完上游拿到真实用量再结算,所以计费不会因为断开而偏少或偏多。断开的那一刻起这次调用就不再占你的并发名额,可以马上发下一个请求。
  • 生图按张、视频按秒,和文本一样按线计价:一个模型挂几条线路,每条按自己的价;先走最便宜的,失败换线就按换到的那条收,所以 /v1/models 每档给的是区间(cu ~ cu_max)。预扣按候选里最贵那条,结算按实际那条,差额当场退回。参考图不另收费。失败不收。
  • 失败的尝试不计费:首字节之前换线、全部线路都失败(503)、被拒(4xx)都不收。换线时按实际完成请求的那条线的价收,被放弃的那几次尝试(包括同一条线重试、为抢首字节同时发出又被取消的那一路)上游即使已经收了我们的钱,也不转给你。
  • 从余额按量扣费(额度用完、或没有订阅):每次调用按 1 元 = 500 CU 折成金额,精确到 0.001 分累计,满 1 分扣一次,不足 1 分的留到之后一起扣,不逐笔向上取整。一次调用完成时实际用量超出剩余余额或月度上限的,扣到余额为 0(或上限为止),超出的部分不收,之后按量续用暂停,直到充值或下个月上限恢复(429 / 403 会说明是余额不足还是已达上限)。
  • 预扣在调用开始时按调度选中的线估、包括工具定义;换到一条更贵的线时按那条线补预扣,结算按实际服务的线。预扣只影响并发占用和准入,不影响收多少钱。
  • 牌价之外另计的几项(模型上游确实另外收钱的,按上游的规则计,/v1/models 每个模型的 pricing_tiers 和控制台模型详情里列着):长上下文阶梯——输入(含缓存)超过阈值(GPT 系目前是 272K)时,整次按倍数计(输入、缓存 × 2,输出 × 1.5);1 小时缓存写入——请求里 cache_control 写了 ttl: "1h" 的那部分缓存写入按输入系数 × 2 计(5 分钟的照常按缓存写系数);fast 模式——/v1/messages 带 speed: "fast" 时整次乘模型的 fast 倍数;网页搜索——Responses 的 web_search 工具 / Anthropic 服务端搜索按次另计;托管生图——Responses 的 image_generation 工具按张另计。这些只在这次调用实际走的那条线按用量计费时另计,包月线路上一项都不收(同一个模型可能有的线收、有的线不收:pricing_tiers.applies_on 是 metered_lines_only,模型有包月线路时带 some_lines_exempt: true)。这些都已含在这一笔的 CU 里,用量明细的链路会写明加了哪一项。
  • 已下架的模型:点名调用返回 410 model_retired,不发出、不计费,错误信息里给替代模型。

什么时候该重试

情况建议
429 quota_exceeded / concurrency_exceeded看 retry-after 和三个额度头再决定;并发超了等前面的请求结束
503 all_upstreams_failed可以指数退避重试;用 auto 时网关已经替你换过线路和能力组
400 upstream_rejected / capability_unavailable不要原样重试,结果不会变:改提示词,或去掉对应要求
流式中途 upstream_interrupted已产出部分已计费;一个字都没产出就断的不计费。重新发起请求
流式等了 20 秒以上才出错这时响应头已经是 200(等待期间每 15 秒发一行 : keepalive 注释防止连接被掐),错误以流里的错误事件给出,码和上面各行一样,按码处理
视频任务 generation_failed未计费,可以直接重新提交

全部错误码的表在快速接入页的「错误码」一节。