API 文档
完全兼容 OpenAI Python / Node SDK,把 base_url 替换成下方地址即可使用全部模型。
https://api.xsai5.xyz/v1
Authorization: Bearer xsai_sk_…
5 分钟入门
三步跑通你的第一个请求。
-
1. 获取 API 密钥
登录后进入控制台 → API 密钥,新建一把密钥,复制完整
xsai_sk_…字符串。 -
2. 选择模型
在API 中转找到目标模型,复制它的模型 id;或者直接调
GET /v1/models列出当前这把密钥能用的全部模型。 -
3. 发送请求
下面是用官方 OpenAI SDK 调用的最小示例:
# pip install openai
from openai import OpenAI
client = OpenAI(
base_url="https://api.xsai5.xyz/v1",
api_key="xsai_sk_…",
)
response = client.chat.completions.create(
model="gpt-5.5",
messages=[
{"role": "user", "content": "你好,介绍一下你自己。"},
],
)
print(response.choices[0].message.content)
// npm install openai
import OpenAI from "openai";
const client = new OpenAI({
baseURL: "https://api.xsai5.xyz/v1",
apiKey: "xsai_sk_…",
});
const response = await client.chat.completions.create({
model: "gpt-5.5",
messages: [
{ role: "user", content: "你好,介绍一下你自己。" },
],
});
console.log(response.choices[0].message.content);
curl https://api.xsai5.xyz/v1/chat/completions \
-H "Authorization: Bearer xsai_sk_…" \
-H "Content-Type: application/json" \
-d '{
"model": "gpt-5.5",
"messages": [
{"role": "user", "content": "你好,介绍一下你自己。"}
]
}'
⚠️ 示例里的 gpt-5.5 只是一个当前存在的模型 id,不是保证长期存在的常量。
模型清单会随目录更新变化,调一个已经不在清单里的 id 会得到 404 model_not_found。
正式接入请先 GET /v1/models。
鉴权
所有请求必须在 HTTP Header 里带上 Bearer Token:
Authorization: Bearer xsai_sk_xxxxxxxxxxxxxxxxxxxxxxxx
- 密钥以
xsai_sk_为前缀,仅在创建/重置那一刻可在控制台看到完整明文。 - 每把密钥可单独配置 额度上限、过期时间、允许的模型白名单,详见控制台「API 密钥」标签页。
- 密钥还可以按 IP / Origin / User-Agent 设白名单;设了之后不匹配的调用方会被拒绝。
- 密钥泄露请立即在控制台「重置」,即可生成新密钥并自动失效旧密钥。
鉴权失败的几种情况:缺 Token 或 Token 无效返回 401;密钥已过期返回 401 且
code 为 key_expired;密钥没被授权调用该模型返回 403。
Base URL
统一入口:
https://api.xsai5.xyz/v1
所有端点路径都拼在这之后。例如对话补全完整地址为 https://api.xsai5.xyz/v1/chat/completions。
⚠️ 只有这一个入口需要你手写。 生成出来的图片 / 视频产物会带一个自己的下载地址,那个地址的主机名可能与这里不同, 必须原样使用 —— 详见媒体产物 URL。
模型列表 · GET /v1/models
列出当前这把密钥可调用的全部模型。响应格式与 OpenAI 兼容,并额外带上了两个对接入很有用的字段。
逐个模型的参数说明:模型 API 参考 —— 每个模型能打哪些端点、上下文多长、图像模型各自认哪些参数、视频模型各档位的时长 / 画幅 / 参考素材上限 / 首尾帧,以及计费单价,全都在里面。这份文档由线上目录直接生成, 跟着模型清单一起更新。纯文本,适合直接喂给你的 agent。
models = client.models.list()
for m in models.data:
print(m.id)
curl https://api.xsai5.xyz/v1/models \
-H "Authorization: Bearer xsai_sk_…"
响应示例:
{
"object": "list",
"data": [
{
"id": "gpt-5.5",
"object": "model",
"owned_by": "nexai",
"created": 0,
"context_length": 1050000,
"max_input_tokens": 1050000,
"capabilities": ["text", "streaming", "tools", "vision", "reasoning"]
}
]
}
两个 OpenAI 规范之外的字段
context_length/max_input_tokens— 这个模型真实的上下文窗口(两个键同值)。 OpenAI 兼容客户端读context_length;Claude Code / Anthropic SDK 读max_input_tokens。 官方接口通常不给窗口,于是很多客户端按模型名去猜,对我们目录里的模型经常是错的(差几倍且不会报错, 表现只是「这模型记性不好、很早就开始压缩历史」)。请读这两个字段,不要猜。 取不到时这两个键都不出现(而不是给 0),此时再退回你自己的兜底。 单模型GET /v1/models/{id}与列表是同一份合同。capabilities— 这个模型能做什么,取值来自固定枚举:text、streaming、tools、vision、audio_input、audio_output、reasoning、image_generation、image_edit、video_generation、embedding、rerank。 模型能打哪个端点由它决定:例如没有image_generation的模型 打图像端点会得到400 model_endpoint_mismatch。
⚠️ owned_by 恒为 nexai,不要用它做模型分类。
要判断模型能力请读 capabilities。
对话补全 · POST /v1/chat/completions
主力端点,覆盖文本对话、流式输出、工具调用、视觉理解、推理模型。
请求参数
modelstring · 必填 — 见 模型列表 返回的 idmessagesarray · 必填 — OpenAI 标准 messages 数组streamboolean — true 时返回 SSE 流式响应,详见 流式响应toolsarray — function calling,详见 工具调用temperature/top_p/max_tokens等所有 OpenAI 兼容参数原样送达模型
最小示例
response = client.chat.completions.create(
model="gpt-5.5",
messages=[
{"role": "system", "content": "你是个资深的 Python 工程师。"},
{"role": "user", "content": "用 Python 写一个快速排序。"},
],
temperature=0.7,
max_tokens=1000,
)
print(response.choices[0].message.content)
const response = await client.chat.completions.create({
model: "gpt-5.5",
messages: [
{ role: "system", content: "你是个资深的 Python 工程师。" },
{ role: "user", content: "用 Python 写一个快速排序。" },
],
temperature: 0.7,
max_tokens: 1000,
});
console.log(response.choices[0].message.content);
curl https://api.xsai5.xyz/v1/chat/completions \
-H "Authorization: Bearer xsai_sk_…" \
-H "Content-Type: application/json" \
-d '{
"model": "gpt-5.5",
"messages": [
{"role": "system", "content": "你是个资深的 Python 工程师。"},
{"role": "user", "content": "用 Python 写一个快速排序。"}
],
"temperature": 0.7,
"max_tokens": 1000
}'
响应示例
{
"id": "chatcmpl-xxxx",
"object": "chat.completion",
"model": "gpt-5.5",
"choices": [
{
"index": 0,
"message": { "role": "assistant", "content": "..." },
"finish_reason": "stop"
}
],
"usage": {
"prompt_tokens": 32,
"completion_tokens": 240,
"total_tokens": 272
}
}
兼容协议
同一个模型 id 可以用三种协议调用,请求体会被自动转换,效果一致 —— 用你手上 SDK 最顺的那种即可,不需要为了换协议换模型。
| 协议 | 端点 | 典型客户端 |
|---|---|---|
| OpenAI | POST /v1/chat/completionsPOST /v1/responsesPOST /v1/completions |
openai SDK、Cherry Studio、Cline |
| Anthropic | POST /v1/messages |
anthropic SDK、Claude Code |
| Gemini | POST /v1/gemini/generateContentPOST /v1/gemini/streamGenerateContent |
google-genai SDK |
# 用 Anthropic 协议调同一个中转
curl https://api.xsai5.xyz/v1/messages \
-H "Authorization: Bearer xsai_sk_…" \
-H "Content-Type: application/json" \
-d '{
"model": "claude-opus-5",
"max_tokens": 1024,
"messages": [{"role": "user", "content": "你好"}]
}'
其余端点:POST /v1/embeddings(字段 model、input)、
POST /v1/rerank(字段 model、query、documents)。
图像 API
以下是当前中转真正实现的图片接口。可用的图片模型以 GET /v1/models
返回(capabilities 含 image_generation)为准。
⭐ 先查这个模型认哪些参数 · GET /v1/images/capabilities
图像参数不是全局一套,逐个模型完全不同。同一个 background: "transparent",
有的模型真能出透明图,有的会直接返回 400,有的只接受 auto。
一份「图像生成通用参数」的说明会把这三件事说成同一件 —— 而照那种说明发请求,
最坏的结局是请求成功了但东西不对,钱照扣、没有任何报错。
# 全部图片模型
curl https://api.xsai5.xyz/v1/images/capabilities \
-H "Authorization: Bearer xsai_sk_…"
# 只要其中一个:加 ?model=
curl "https://api.xsai5.xyz/v1/images/capabilities?model=gpt-image-2" \
-H "Authorization: Bearer xsai_sk_…"
每个模型返回一张卡片:
{
"object": "list",
"version": "…",
"data": [
{
"id": "gpt-image-2",
"displayName": "GPT (图像) 2",
"operations": ["generation", "edit"],
"parameters": [
{ "name": "prompt", "required": true,
"operations": null, "enforced": false, "kind": "free" },
{ "name": "n", "required": false,
"operations": ["generation", "edit"], "enforced": true,
"kind": "integer", "min": 1, "max": 10 },
{ "name": "background", "required": false,
"operations": ["generation", "edit"], "enforced": false,
"kind": "enum", "values": ["auto", "transparent", "opaque"] }
],
"supportsTransparentBackground": true,
"available": true
}
]
}
operations— 这个模型支持哪些操作(generation/edit)。 卡片上有的操作,点下去不会必然失败;反过来,卡片上没有的不要提供入口。- ⭐
parameters是一张白名单,不是全集。 对这个模型「发了会被静默丢弃」和「发了会直接报错」的参数根本不会出现在这里。 所以正确的读法是:卡片上没有的参数,就不要发 —— 这样你的界面上不会出现一个按下去无声无息、或者必然报错的旋钮。 parameters[].enforced—true表示严格生效: 结果不符会判为失败,不会把不对的结果交给你。false表示参数会照发,但模型不保证完全照办。parameters[].kind— 取值形状,用来渲染控件:enum(配values)、integer(配min/max)、free(自由文本)。parameters[].operations— 这个参数在哪些操作下可用;null表示不限。supportsTransparentBackground— 是否可以要透明背景。- 响应带
ETag,可用If-None-Match做条件请求,内容不变时返回304;version只由内容决定,内容没变就不变。
⚠️ 「卡片上没有」的两种原因,代价差别很大。
一种是发了直接返回 400(不计费,你立刻知道该改什么);
另一种是在请求发出前被静默丢弃 ——
请求照样成功、照样计费,只是那个参数从来没到过模型,而且不会有任何警告。
后一种是「不查能力卡」最贵的失败:你以为自己在控制尺寸或数量,其实没有。
想看某个模型逐字段的具体待遇,见 模型 API 参考。
⛔ 不要在你的客户端里再写一份参数校验表。
服务端的能力卡是唯一权威,两份必然分叉 —— 而分叉的表现正是「文档说能用、参数被静默丢弃」。
也不要做一个对所有图片模型通用的「尺寸」下拉框:同一个 size,
有的模型枚举外报错、有的静默丢弃、有的直接忽略。
POST /v1/images/generations · 同步生成
JSON 请求。model、prompt 必填;其余字段
n、size、quality、output_format、
background、input_fidelity、response_format
是否生效以能力卡为准。返回 OpenAI Images 兼容的 data[].url。
response = client.images.generate(
model="gpt-image-2",
prompt="A cat playing piano in space, watercolor style",
size="1024x1024",
n=1,
)
print(response.data[0].url)
curl https://api.xsai5.xyz/v1/images/generations \
-H "Authorization: Bearer xsai_sk_…" \
-H "Content-Type: application/json" \
-d '{
"model": "gpt-image-2",
"prompt": "A cat playing piano in space, watercolor style",
"size": "1024x1024",
"n": 1
}'
n的实际上限是 8:发更大的值会被夹到 8,不会报错。 ⚠️ 部分模型的能力卡把max写作10(那是参数契约的取值域), 以 8 为准。n是否严格生效逐模型不同:有的模型出不满会判为失败(不会把少的交给你), 有的模型恒出 1 张且不报错。要多张最稳妥的做法是发多次请求(各自计费)。response_format不传时只给url;传b64_json时 同时给b64_json和url。
透明背景 · background
需要一张可以直接叠到别的画面上的图(商品图、图标、贴纸)时,加 background: "transparent"。
只传参数即可,不需要在提示词里额外说明 —— 需要的措辞由服务端按需补齐。
curl https://api.xsai5.xyz/v1/images/generations \
-H "Authorization: Bearer xsai_sk_…" \
-H "Content-Type: application/json" \
-d '{
"model": "gpt-image-2",
"prompt": "一只戴墨镜的柴犬",
"background": "transparent",
"output_format": "png"
}'
transparent出透明底;opaque强制不透明底;auto(默认)由模型自己决定。- 必须配
output_format: "png"或"webp"。 JPEG 没有透明通道,配transparent会被直接拒绝(image_background_format_conflict) —— 我们宁可报错,也不给你一张看起来对、其实是白底的图。 - 不是所有图像模型都支持指定背景,以能力卡的
supportsTransparentBackground为准。不支持的模型会在请求发出前返回400并说明该改用哪个模型,不计费。 - ⭐ 产物在交付前会被校验有没有真的透明通道。
没有透明通道的结果会被判为失败并自动改走另一条路重试,而不是直接交给你 ——
这道校验就是为了不出现「
200+ 扣费 + 一张白底图」。 拿到结果后仍建议你自己确认一次 alpha 通道,这是一次成本极低的检查。 - ⚠️ 代价是透明请求更慢也更容易失败,单次耗时可能到 1–2 分钟。 失败时重试一次通常就好。
POST /v1/images/edits · 图生图
只接受 multipart/form-data。文件字段为 image 或重复的 image[];
文本字段为 prompt、model、n、size、quality、
output_format、response_format、background、
input_fidelity、user。
curl https://api.xsai5.xyz/v1/images/edits \
-H "Authorization: Bearer xsai_sk_…" \
-F model=gpt-image-2 \
-F image=@source.png \
-F prompt="把背景换成雪山日出"
| 约束 | 说明 |
|---|---|
| 单张体积 | 不超过 25 MiB |
| 单张像素 | 不超过 64,000,000(宽 × 高) |
| 格式 | image/png、image/jpeg、image/webp |
| 能不能编辑 | 模型的 capabilities 要含 image_edit,
或能力卡 operations 里有 edit |
⛔ 不要传 mask,也不要在你的界面上提供「局部重绘」入口。
逐条实测过当前所有在售图片能力,没有一条做真正的像素级局部重绘 ——
遮罩洞开在左上、提示词不提位置,主体照样画在正中并盖住受保护区,输出尺寸也会变
(真正的 inpainting 不可能改变画布尺寸)。这个能力在当前供给下不存在。
只想改局部时,请把要保留的内容写进 prompt。
⚠️ 两个端点对 mask 的处理不一样,而编辑端点那种更危险:
你在哪传 mask | 会发生什么 | 计费 |
|---|---|---|
POST /v1/images/generations(JSON) |
请求前直接 400 并说明 |
不计费 |
POST /v1/images/edits(multipart) |
⚠️ 不会报错:遮罩会被送出去,但没有模型真的按它局部重绘, 你拿到的是整图重绘,而且画布尺寸可能变了 | 照常计费 |
⭐ 后者是这份文档里最值得记住的一条:它没有任何报错, 你会拿到一张「看起来像那么回事」的图、付了钱,然后才发现受保护的区域被改掉了、 尺寸也不对。静默拿到错结果,比直接报错糟得多 —— 所以请自己不要发这个字段。
异步任务 · POST /v1/images/jobs
图片通常几十秒内出结果,同步接口够用。不希望长时间占用连接时用异步:
POST /v1/images/jobs 立即返回任务 id,再轮询 GET /v1/images/jobs/{id}。
{
"id": "api_req_…",
"object": "image.generation.job",
"model": "gpt-image-2",
"status": "processing",
"status_label": "生成中",
"status_message": "…",
"stage": "…",
"progress_percent": 40,
"retry_after_seconds": 8,
"elapsed_ms": 12345,
"created_at": "…",
"data": [],
"deducted_units": null,
"deducted_amount_label": null,
"error": null
}
- 图片任务的
status只有这 5 个:processing、succeeded、failed、timeout、cancelled。 (queued/submitting是视频任务才有的,别在图片上等它们。) data仅在succeeded时有内容,形状与同步接口一致。deducted_units未完成时为null;完成后deducted_amount_label形如"¥0.15"。- ⚠️ 按
retry_after_seconds(未完成时为 8 秒)轮询,不要更密; 响应头也带Retry-After。
文件接口
POST /v1/files:multipart/form-data上传参考素材,purpose=user_data;视频接口引用返回的file_nexai_*。GET /v1/files/{id}、GET /v1/files/{id}/content、DELETE /v1/files/{id}:文件元数据、内容下载、删除。
逐个图像模型
⛔ 这一节没有「通用参数表」,因为不存在这种东西。 同一个字段在不同模型上的结果可以是「真生效」「静默丢弃」「直接 400」三种, 而中间那种不会报错。照通用表发请求,最坏的结局是请求成功、 钱照扣、东西不对。所以下面一个模型一节,各说各的。
gemini-3.1-flash-image · Gemini 3.1 极速 (图像)
- 计费:¥0.15 / 张(按次计费,与图片尺寸、提示词长度无关)
- 可用端点:
POST /v1/images/generations、POST /v1/images/edits(图生图)、POST /v1/images/jobs(异步) - 透明背景:不支持 —— 发
background会在请求前直接返回400并说明,不计费
| 字段 | 取值 | 发了会怎样 |
|---|---|---|
prompt 必填 | string | 按原样送达模型 |
image | image[] | 按原样送达模型 |
size | 尺寸枚举 | 发了不生效:请求前会被丢弃(不会报错,但也不会起作用) |
n | 整数 1–4 | 发了不生效:请求前会被丢弃(不会报错,但也不会起作用) |
quality | auto low medium high standard hd | 发了不生效:请求前会被丢弃(不会报错,但也不会起作用) |
output_format | png jpeg webp | 发了不生效:请求前会被丢弃(不会报错,但也不会起作用) |
background | string | 不接受:发了会直接返回参数错误 |
input_fidelity | string | 不接受:发了会直接返回参数错误 |
mask | — | 别发:当前没有任何图片能力做真正的像素级局部重绘。打 /v1/images/generations 会 400(不计费);打 /v1/images/edits 不会报错,但你拿到的是整图重绘、画布尺寸可能改变,且照常计费 |
curl https://api.xsai5.xyz/v1/images/generations \
-H "Authorization: Bearer xsai_sk_…" \
-H "Content-Type: application/json" \
-d '{
"model": "gemini-3.1-flash-image",
"prompt": "一只戴墨镜的柴犬"
}'
gpt-image-2 · GPT (图像) 2
- 计费:¥0.15 / 张(按次计费,与图片尺寸、提示词长度无关)
- 可用端点:
POST /v1/images/generations、POST /v1/images/edits(图生图)、POST /v1/images/jobs(异步) - 透明背景:支持,传
background: "transparent"并配png/webp
| 字段 | 取值 | 发了会怎样 |
|---|---|---|
prompt 必填 | string | 按原样送达模型 |
image | image[] | 按原样送达模型 |
size | 尺寸枚举 | 会照发,但不保证严格遵守 |
n | 整数 1–10 | 严格生效:结果不符会判为失败,不会把不对的结果交给你 |
quality | auto low medium high standard hd | 会照发,但不保证严格遵守 |
output_format | png jpeg webp | 会照发,但不保证严格遵守 |
background | auto transparent opaque | 会照发,但不保证严格遵守 |
input_fidelity | low high | 会照发,但不保证严格遵守 |
mask | — | 别发:当前没有任何图片能力做真正的像素级局部重绘。打 /v1/images/generations 会 400(不计费);打 /v1/images/edits 不会报错,但你拿到的是整图重绘、画布尺寸可能改变,且照常计费 |
curl https://api.xsai5.xyz/v1/images/generations \
-H "Authorization: Bearer xsai_sk_…" \
-H "Content-Type: application/json" \
-d '{
"model": "gpt-image-2",
"prompt": "一只戴墨镜的柴犬",
"size": "1024x1024",
"background": "transparent",
"output_format": "png"
}'
gpt-image-2.5 · GPT (图像) 2.5
- 计费:¥0.25 / 张(按次计费,与图片尺寸、提示词长度无关)
- 可用端点:
POST /v1/images/generations、POST /v1/images/edits(图生图)、POST /v1/images/jobs(异步) - 透明背景:支持,传
background: "transparent"并配png/webp
| 字段 | 取值 | 发了会怎样 |
|---|---|---|
prompt 必填 | string | 按原样送达模型 |
image | image[] | 按原样送达模型 |
size | 尺寸枚举 | 会照发,但不保证严格遵守 |
n | 整数 1–10 | 严格生效:结果不符会判为失败,不会把不对的结果交给你 |
quality | auto low medium high standard hd | 会照发,但不保证严格遵守 |
output_format | png jpeg webp | 会照发,但不保证严格遵守 |
background | auto transparent opaque | 会照发,但不保证严格遵守 |
input_fidelity | low high | 会照发,但不保证严格遵守 |
mask | — | 别发:当前没有任何图片能力做真正的像素级局部重绘。打 /v1/images/generations 会 400(不计费);打 /v1/images/edits 不会报错,但你拿到的是整图重绘、画布尺寸可能改变,且照常计费 |
curl https://api.xsai5.xyz/v1/images/generations \
-H "Authorization: Bearer xsai_sk_…" \
-H "Content-Type: application/json" \
-d '{
"model": "gpt-image-2.5",
"prompt": "一只戴墨镜的柴犬",
"size": "1024x1024",
"background": "transparent",
"output_format": "png"
}'
grok-imagine-image-2.0 · Grok Imagine (图像) 2.0
- 计费:¥0.15 / 张(按次计费,与图片尺寸、提示词长度无关)
- 可用端点:
POST /v1/images/generations、POST /v1/images/edits(图生图)、POST /v1/images/jobs(异步) - 透明背景:不支持 —— 发
background会在请求前直接返回400并说明,不计费
| 字段 | 取值 | 发了会怎样 |
|---|---|---|
prompt 必填 | string | 按原样送达模型 |
image | image[] | 按原样送达模型 |
size | 尺寸枚举 | 会照发,但不保证严格遵守 |
n | 整数 1–10 | 会照发,但不保证严格遵守 |
quality | auto low medium high standard hd | 会照发,但不保证严格遵守 |
output_format | png jpeg webp | 会照发,但不保证严格遵守 |
background | auto transparent opaque | 只接受 auto:这个模型没有指定背景的能力,发 transparent / opaque 会在请求前直接返回错误并说明,不计费 |
input_fidelity | low high | 会照发,但不保证严格遵守 |
mask | — | 别发:当前没有任何图片能力做真正的像素级局部重绘。打 /v1/images/generations 会 400(不计费);打 /v1/images/edits 不会报错,但你拿到的是整图重绘、画布尺寸可能改变,且照常计费 |
curl https://api.xsai5.xyz/v1/images/generations \
-H "Authorization: Bearer xsai_sk_…" \
-H "Content-Type: application/json" \
-d '{
"model": "grok-imagine-image-2.0",
"prompt": "一只戴墨镜的柴犬",
"size": "1024x1024"
}'
qwen-image-2.1 · 通义千问 (图像) 2.1
- 计费:¥0 / 张(按次计费,与图片尺寸、提示词长度无关)
- 可用端点:
POST /v1/images/generations—— 只支持文生图,不支持图生图 - 透明背景:不支持 —— 发
background会在请求前直接返回400并说明,不计费
| 字段 | 取值 | 发了会怎样 |
|---|---|---|
prompt 必填 | string | 按原样送达模型 |
size | 尺寸枚举 | 会照发,但不保证严格遵守 |
n | 整数 1–10 | 会照发,但不保证严格遵守 |
quality | auto low medium high standard hd | 会照发,但不保证严格遵守 |
output_format | png jpeg webp | 会照发,但不保证严格遵守 |
background | auto transparent opaque | 只接受 auto:这个模型没有指定背景的能力,发 transparent / opaque 会在请求前直接返回错误并说明,不计费 |
mask | — | 别发:当前没有任何图片能力做真正的像素级局部重绘。打 /v1/images/generations 会 400(不计费);打 /v1/images/edits 不会报错,但你拿到的是整图重绘、画布尺寸可能改变,且照常计费 |
curl https://api.xsai5.xyz/v1/images/generations \
-H "Authorization: Bearer xsai_sk_…" \
-H "Content-Type: application/json" \
-d '{
"model": "qwen-image-2.1",
"prompt": "一只戴墨镜的柴犬",
"size": "1024x1024"
}'
视频 API · POST /v1/videos
异步任务:创建后返回任务 id,轮询到完成为止。 视频单次成本比图像高得多,参数选错的代价也大得多,所以先查能力再下单。
先查这个模型认哪些参数 · GET /v1/videos/capabilities
每个视频模型认的时长档位、画幅、分辨率、参考素材上限各不相同,而且会随目录更新变化。 这个端点返回当前真实生效的一份,不要把参数写死在你的代码里。
# 全部视频模型;加 ?model=<模型 id> 只取其中一个
curl https://api.xsai5.xyz/v1/videos/capabilities \
-H "Authorization: Bearer xsai_sk_…"
返回里每个模型一张卡片:
duration.options— 认哪些秒数;duration.fixed为 true 表示时长不可调,别发secondsaspectRatio.options/resolution.options—null表示未声明,那就一个都别发: 未声明的字段中转不会替你校验,发出去可能被忽略,而这次生成照常计费reference.images / videos / audios— 参考素材各自的数量上限、体积上限与格式reference.firstLastFrame— 是否支持首尾帧,mustPair为 true 时必须首尾同时给typicalSeconds— 这个模型近期真实的耗时分位数(p50/p90), 样本不足时为null,用来给用户一个合理的等待预期maintained— 为false表示我们还没有为它做参数声明, 此时不要猜参数,只发model+prompt最稳
响应带 ETag,可用 If-None-Match 做条件请求,内容不变时返回 304。
创建任务
curl https://api.xsai5.xyz/v1/videos \
-H "Authorization: Bearer xsai_sk_…" \
-H "Content-Type: application/json" \
-d '{
"model": "seedance-2.0",
"prompt": "清晨山谷薄雾流动,阳光穿透林间,镜头平稳前推",
"seconds": 4,
"aspect_ratio": "16:9"
}'
返回 202 与任务 id,随后轮询 GET /v1/videos/{id}。
响应里的 retry_after_seconds 是建议的轮询间隔。
视频任务端点与状态
POST /v1/videos:创建视频任务;兼容别名POST /v1/video/generations、POST /v1/videos/generations。GET /v1/videos/{id}:轮询任务状态,成功内容通常在data[0].url。POST /v1/videos/{id}/cancel:取消尚未完成的任务。- 视频请求通用字段为
model、prompt、seconds、aspect_ratio、resolution、audio、seed、negative_prompt; 是否可用必须以能力卡片为准。
视频任务的 status 比图片多几个:进行中有
queued、submitting、submitted、processing;
终态有 succeeded、failed、timeout、cancelled,
以及 submission_unknown(提交结果未知)。
cancelled 是独立终态,不要把它显示成「生成失败」——
那会让用户以为是我们的问题,于是再花一次钱重试。
参考素材与首尾帧
先用 POST /v1/files(multipart/form-data)上传,拿到 file_nexai_… 的 id 再引用;也可以直接给公网可访问的 URL。
# 1) 上传参考图
curl https://api.xsai5.xyz/v1/files \
-H "Authorization: Bearer xsai_sk_…" \
-F purpose=user_data -F file=@first.png
# 2) 引用它(images 是参考图;首尾帧走 first_image_url / last_image_url)
curl https://api.xsai5.xyz/v1/videos \
-H "Authorization: Bearer xsai_sk_…" \
-H "Content-Type: application/json" \
-d '{
"model": "seedance-2.0",
"prompt": "以参考图为起点,镜头缓缓拉远",
"seconds": 4,
"images": ["file_nexai_…"]
}'
首尾帧与普通参考素材互斥:用了
first_image_url / last_image_url 就不要再传
images / videos / audios。
是否支持、是否必须成对,以 reference.firstLastFrame 为准。
参数不合法的任务不计费:中转先受理再校验,作业会转
failed 并带上原因,deducted_units 为 0。
逐个视频模型
视频模型认的时长档位、画幅、分辨率、参考素材上限各不相同,
有的模型还分多个档位、档位之间能力也不一样。
下面一个模型一节;模型有多档的,逐档列出。
⚠️ 写着「尚未取证」的地方是我们没测过,不是「不支持」——
请以 GET /v1/videos/capabilities 为准,别按「不支持」处理。
minimax-h3 · Minimax H3
- 计费:¥5 / 条(时长不影响价格)
- 端点:
POST /v1/videos创建任务 →GET /v1/videos/{id}轮询
这个模型有 4 个档位:2K / 480P / 768P / 标准 —— 不同档位能力不同,逐档列在下面。
2K 档
| 字段 | 取值 | 说明 |
|---|---|---|
prompt 必填 | 文本 | 想生成什么 |
seconds | 4 5 6 7 8 9 10 11 12 13 14 15 | 秒;只接受这些值 |
resolution | 2K | 选这一档就传这个值 |
aspect_ratio | 16:9 4:3 1:1 3:4 9:16 21:9 adaptive | 画幅 |
images | URL 数组,最多 9 个 | 参考图 |
videos | URL 数组,最多 3 个 | 参考视频 |
audios | URL 数组,最多 3 个 | 参考音频 |
first_image_url / last_image_url | 图片 URL | 首尾帧 |
curl https://api.xsai5.xyz/v1/videos \
-H "Authorization: Bearer xsai_sk_…" \
-H "Content-Type: application/json" \
-d '{
"model": "minimax-h3",
"prompt": "一只柴犬在雪地里奔跑",
"seconds": 5,
"resolution": "2K",
"aspect_ratio": "16:9"
}'
480P 档
| 字段 | 取值 | 说明 |
|---|---|---|
prompt 必填 | 文本 | 想生成什么 |
seconds | 5 6 7 8 9 10 11 12 13 14 15 | 秒;只接受这些值 |
resolution | 480P | 选这一档就传这个值 |
aspect_ratio | 16:9 4:3 1:1 3:4 9:16 21:9 adaptive | 画幅 |
images | URL 数组,最多 9 个 | 参考图 |
videos | URL 数组,最多 3 个 | 参考视频 |
audios | URL 数组,最多 3 个 | 参考音频 |
first_image_url / last_image_url | 图片 URL | 首尾帧 |
curl https://api.xsai5.xyz/v1/videos \
-H "Authorization: Bearer xsai_sk_…" \
-H "Content-Type: application/json" \
-d '{
"model": "minimax-h3",
"prompt": "一只柴犬在雪地里奔跑",
"seconds": 6,
"resolution": "480P",
"aspect_ratio": "16:9"
}'
768P 档
| 字段 | 取值 | 说明 |
|---|---|---|
prompt 必填 | 文本 | 想生成什么 |
seconds | 4 5 6 7 8 9 10 11 12 13 14 15 | 秒;只接受这些值 |
resolution | 768P | 选这一档就传这个值 |
aspect_ratio | 16:9 4:3 1:1 3:4 9:16 21:9 adaptive | 画幅 |
images | URL 数组,最多 9 个 | 参考图 |
videos | URL 数组,最多 3 个 | 参考视频 |
audios | URL 数组,最多 3 个 | 参考音频 |
first_image_url / last_image_url | 图片 URL | 首尾帧 |
curl https://api.xsai5.xyz/v1/videos \
-H "Authorization: Bearer xsai_sk_…" \
-H "Content-Type: application/json" \
-d '{
"model": "minimax-h3",
"prompt": "一只柴犬在雪地里奔跑",
"seconds": 5,
"resolution": "768P",
"aspect_ratio": "16:9"
}'
标准 档
| 字段 | 取值 | 说明 |
|---|---|---|
prompt 必填 | 文本 | 想生成什么 |
seconds | 4 5 6 7 8 9 10 11 12 13 14 15 | 秒;只接受这些值 |
images | URL 数组,最多 9 个 | 参考图 |
videos | — | 不支持参考视频 |
audios | URL 数组,最多 3 个 | 参考音频 |
first_image_url / last_image_url | — | 不支持首尾帧 |
- 标准 档不支持首尾帧,其他档可以用。
curl https://api.xsai5.xyz/v1/videos \
-H "Authorization: Bearer xsai_sk_…" \
-H "Content-Type: application/json" \
-d '{
"model": "minimax-h3",
"prompt": "一只柴犬在雪地里奔跑",
"seconds": 5
}'
omni · Omni 视频
- 计费:¥2.43 / 条(时长不影响价格)
- 端点:
POST /v1/videos创建任务 →GET /v1/videos/{id}轮询
| 字段 | 取值 | 说明 |
|---|---|---|
prompt 必填 | 文本 | 想生成什么 |
seconds | 4 6 8 10 20 30 40 | 秒;只接受这些值 |
resolution | 720p | 选这一档就传这个值 |
aspect_ratio | 16:9 9:16 | 画幅 |
images | URL 数组,最多 5 个 | 参考图 |
videos | URL 数组,最多 2 个 | 参考视频 |
audios | — | 不支持参考音频 |
first_image_url / last_image_url | 图片 URL | 首尾帧 |
curl https://api.xsai5.xyz/v1/videos \
-H "Authorization: Bearer xsai_sk_…" \
-H "Content-Type: application/json" \
-d '{
"model": "omni",
"prompt": "一只柴犬在雪地里奔跑",
"seconds": 6,
"resolution": "720p",
"aspect_ratio": "16:9"
}'
seedance-2.0 · Seedance 2.0(9图)
- 计费:¥8.7 / 条(时长不影响价格)
- 端点:
POST /v1/videos创建任务 →GET /v1/videos/{id}轮询
| 字段 | 取值 | 说明 |
|---|---|---|
prompt 必填 | 文本 | 想生成什么 |
seconds | 5 10 15 | 秒;只接受这些值 |
resolution | 720p | 选这一档就传这个值 |
aspect_ratio | 16:9 9:16 1:1 | 画幅 |
images | URL 数组,最多 9 个 | 参考图 |
videos | — | 不支持参考视频 |
audios | — | 不支持参考音频 |
first_image_url / last_image_url | — | 不支持首尾帧 |
curl https://api.xsai5.xyz/v1/videos \
-H "Authorization: Bearer xsai_sk_…" \
-H "Content-Type: application/json" \
-d '{
"model": "seedance-2.0",
"prompt": "一只柴犬在雪地里奔跑",
"seconds": 10,
"resolution": "720p",
"aspect_ratio": "16:9"
}'
seedance2.5 · Seedance 2.5(30秒 720p)
- 计费:¥9 / 条(时长不影响价格)
- 端点:
POST /v1/videos创建任务 →GET /v1/videos/{id}轮询
这个模型有 2 个档位:720p / 标准 —— 不同档位能力不同,逐档列在下面。
720p 档
| 字段 | 取值 | 说明 |
|---|---|---|
prompt 必填 | 文本 | 想生成什么 |
seconds | 30 | 秒;只接受这些值 |
resolution | 720p | 选这一档就传这个值 |
aspect_ratio | 16:9 9:16 1:1 21:9 4:3 3:4 | 画幅 |
images | URL 数组,最多 30 个 | 参考图 |
videos | URL 数组,最多 10 个 | 参考视频 |
audios | URL 数组,最多 10 个 | 参考音频 |
first_image_url / last_image_url | — | 不支持首尾帧 |
curl https://api.xsai5.xyz/v1/videos \
-H "Authorization: Bearer xsai_sk_…" \
-H "Content-Type: application/json" \
-d '{
"model": "seedance2.5",
"prompt": "一只柴犬在雪地里奔跑",
"seconds": 30,
"resolution": "720p",
"aspect_ratio": "16:9"
}'
标准 档
| 字段 | 取值 | 说明 |
|---|---|---|
prompt 必填 | 文本 | 想生成什么 |
seconds | 30 | 秒;只接受这些值 |
images | — | 不支持参考图 |
videos | — | 不支持参考视频 |
audios | — | 不支持参考音频 |
first_image_url / last_image_url | — | 不支持首尾帧 |
curl https://api.xsai5.xyz/v1/videos \
-H "Authorization: Bearer xsai_sk_…" \
-H "Content-Type: application/json" \
-d '{
"model": "seedance2.5",
"prompt": "一只柴犬在雪地里奔跑",
"seconds": 30
}'
流式响应
在请求体里加 "stream": true,服务器将以 Server-Sent Events 形式逐个 token 推送增量。
stream = client.chat.completions.create(
model="gpt-5.5",
messages=[{"role": "user", "content": "讲一个简短的故事"}],
stream=True,
)
for chunk in stream:
delta = chunk.choices[0].delta.content or ""
print(delta, end="", flush=True)
const stream = await client.chat.completions.create({
model: "gpt-5.5",
messages: [{ role: "user", content: "讲一个简短的故事" }],
stream: true,
});
for await (const chunk of stream) {
process.stdout.write(chunk.choices[0]?.delta?.content || "");
}
- 响应 Content-Type 为
text/event-stream,每条事件data: {json}\n\n - 结束事件为
data: [DONE] - 计费仍按总 token 计算,与非流式一致
- ⛔ 图片和视频生成没有流式:它们要么同步返回结果,要么走异步任务轮询。
不要给这两类端点发
stream
工具调用(Function Calling)
capabilities 里含 tools 的模型,原生兼容 OpenAI tools 格式。
tools = [{
"type": "function",
"function": {
"name": "get_weather",
"description": "查询某城市的当前天气",
"parameters": {
"type": "object",
"properties": {
"city": {"type": "string", "description": "城市名"}
},
"required": ["city"]
}
}
}]
response = client.chat.completions.create(
model="gpt-5.5",
messages=[{"role": "user", "content": "北京今天天气怎么样?"}],
tools=tools,
tool_choice="auto",
)
tool_call = response.choices[0].message.tool_calls[0]
print(tool_call.function.name, tool_call.function.arguments)
视觉理解
capabilities 里含 vision 的模型可以在 messages.content 里放图片:
response = client.chat.completions.create(
model="gpt-5.5",
messages=[{
"role": "user",
"content": [
{"type": "text", "text": "这张图里有什么?"},
{"type": "image_url", "image_url": {
"url": "https://example.com/photo.jpg"
}}
]
}],
)
print(response.choices[0].message.content)
图片可以是 公开 URL 或 base64 data URI(data:image/jpeg;base64,…)。
媒体产物 URL
图片和视频生成成功后,data[].url 是一个带签名的下载地址。
这四条约束每一条都踩过:
| 约束 | 踩了会怎样 | |
|---|---|---|
| 1 | 原样使用,不做任何字符串加工 | URL 带签名与 expires,签名里可能含 -;
在 shell 里不加引号直接传变量会被截断,签名校验失败 |
| 2 | 主机名必须用返回值里的那个 | 产物按存储位置落在不同主机上。
⛔ 改成 api.xsai5.xyz 去读会读不到 |
| 3 | 默认有效期 600 秒 | 过期后需要重新获取;异步任务可以再 GET 一次拿新链接 |
| 4 | 产物保留 90 天 | 需要长期留存请自行下载归档 |
需要内联字节而不是链接时,图片接口传 response_format: "b64_json",
此时 b64_json 和 url 会同时返回。
错误码
所有错误响应遵循 OpenAI 错误格式:
{
"error": {
"message": "API 密钥已过期",
"type": "authentication_error",
"code": "key_expired",
"param": null
}
}
响应头 x-nexai-request-id 是这次请求的 id,报障时请带上它。
type 是粗分类,code 才是具体原因。
分支判断请用 code;type 只适合拿来做兜底归类。
会出现的 type:authentication_error(鉴权)、
permission_error(没权限)、insufficient_quota(余额/额度)、
rate_limit_exceeded(限流)、invalid_request_error(请求本身有问题)、
api_error(服务端)。
你能自己解决的
这一类一律不计费,而且 message 是写给人看的中文原话 ——
直接展示原话即可,它会告诉用户该改什么。
| HTTP | code | 说明 |
|---|---|---|
| 401 | invalid_api_key | 缺少或无效的 API 密钥(type 为 authentication_error) |
| 401 | key_expired | 密钥已过期 |
| 402 | insufficient_quota | 账户余额不足,或密钥额度已用尽 |
| 403 | model_not_allowed_for_key | 这把密钥没被授权调用这个模型(白名单限制) |
| 404 | model_not_found | 没有这个模型 —— 请以 GET /v1/models 为准 |
| 400 | model_endpoint_mismatch | 这个模型不能用这个端点(对照 capabilities) |
| 400 | operation_unsupported | 这个模型不支持该操作 |
| 400 | image_background_unsupported | 这个模型不支持指定背景 —— 原话会告诉你改用哪个模型 |
| 400 | image_background_format_conflict | 透明背景需要 png / webp |
| 400 | image_background_invalid | background 只有 auto / transparent / opaque 三个合法值 |
| 400 | image_size_unsupported | 这个尺寸不被支持 |
| 400 | image_size_not_declared | 这个模型不接受指定尺寸 → 去掉 size |
| 400 | reference_image_required | 编辑至少要一张原图 |
| 400 | duration_unsupported / duration_fixed | 视频时长不在档位内,或这个模型时长不可调 |
| 400 | resolution_unsupported | 视频分辨率不在档位内 |
| 400 | reference_over_limit / reference_kinds_exclusive | 参考素材超上限,或几类素材混用了 |
| 400 | frames_must_pair / frames_mutex_with_refs / frames_unsupported | 首尾帧必须成对、不能与参考素材同用、或这个模型不支持 |
| 400 | moderation_rejected | 内容没通过安全审核 |
| 429 | rate_limited / rate_limit_exceeded | 触发并发限流,建议指数退避重试 |
我们这边的问题
这一类同样不计费,可以放心重试。
| HTTP | code | 说明 |
|---|---|---|
| 503 | no_route_available | 当前排不上,稍后重试 |
| 503 | capacity_unavailable | 暂时排不上算力 |
| 503 | model_channel_unavailable | 这个模型当前不可用 |
| 504 | timeout | 生成超时 |
| 502 | service_error | 统一兜底:生成失败 |
该怎么分流
| 现象 | 该做什么 |
|---|---|
4xx + 上表里的 code | 直接展示 message 原话,用户改参数就能继续 |
429 | 指数退避重试 |
503 | 提示稍后重试,⛔ 不要当成参数错误 |
502 | 提示重试;单次失败重试一次通常就好 |
⚠️ 502 service_error 是兜底文案,不代表你做错了什么。
它盖住了多种情况。看到它提示重试即可,
⛔ 不要据此判断是用户的参数写错了 —— 那会把用户引到一个改不动的方向上去。
计费与限流
计费
- 对话 / 嵌入 / 重排按 真实 token 实时扣费;图片、视频按次计费, 与图片尺寸、提示词长度无关。单价见API 中转与 模型 API 参考
- 缓存命中部分(
prompt_tokens_details.cached_tokens)按对应模型的「缓存输入」价计费 - 失败请求不扣费:上面两张错误码表里的情况都不计费; 参数错误在请求发出前就被拒,更不会产生费用
- 每条请求扣费可在请求记录逐条核对
⚠️ 「不计费」保护不了「静默不生效」。 一个被丢弃的参数不会让请求失败 —— 请求成功、照常计费,只是那个参数没起作用。 这正是要先查能力卡的原因。
限流
- 用户级、密钥级、单模型级三段并发限制(详见控制台设置)
- 触发限流时返回
429,建议指数退避重试
密钥级限制
每把密钥可在控制台单独配置:
- 额度上限:达到金额上限后该密钥停止扣费,账户其他密钥不受影响
- 过期时间:到期后自动失效
- 允许的模型白名单:仅勾选的模型可被该密钥调用,调其他模型返回
403