API 文档
基础地址:https://apicafe.ai/api/v1
生成需要时间,所以 API 是异步的:你提交任务,立刻拿到任务 ID,再通过轮询获取结果。视频接口和图片接口的用法完全一致。
快速开始
1. 在后台的 API Key 页面创建 Key。 Key 只显示一次,请妥善保存。
2. 提交任务:
curl -X POST https://apicafe.ai/api/v1/videos \
-H "Authorization: Bearer sk-..." \
-H "Content-Type: application/json" \
-d '{
"model": "seedance-2.5",
"prompt": "A red paper boat drifts across a calm pond at sunrise",
"duration": 5,
"resolution": "720p"
}'
返回 202 Accepted 和一个任务对象:
{
"id": "0b1f9c0e-6c7a-4d52-9d0e-2f6a1d8b7c11",
"object": "video.task",
"model": "seedance-2.5",
"status": "processing",
"video_url": null,
"error": null,
"credits_charged": 263,
"created_at": "2026-11-09T08:30:00.000Z",
"completed_at": null
}
3. 轮询直到完成:
curl https://apicafe.ai/api/v1/videos/0b1f9c0e-6c7a-4d52-9d0e-2f6a1d8b7c11 \
-H "Authorization: Bearer sk-..."
当 status 变为 succeeded 时,video_url 就是生成好的视频地址。
认证
每个请求都要在 Authorization 请求头里带上你的 Key:
Authorization: Bearer sk-...
不要把 Key 放在前端代码里。被撤销的 Key 会立即失效。
创建 Key 时可以加上限制:额度上限(累计消费上限)、过期日期、模型白名单和 IP 白名单(单个地址或 203.0.113.0/24 这样的 IPv4 段)。把 Key 交给某个应用或同事时,用这些限制把风险控制在可承受的范围内。
创建视频
POST /videos
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| model | string | 是 | 视频模型 ID,例如 seedance-2.5。见模型列表。 |
| prompt | string | 是 | 要生成的内容,1 到 4000 个字符。 |
| duration | integer | 否 | 时长(秒)。每个模型接受自己的范围或固定取值,默认使用模型的默认值。 |
| resolution | string | 否 | 例如 720p,默认使用模型的默认值。 |
| aspect_ratio | string | 否 | 例如 16:9,默认使用模型的默认值。 |
| audio | boolean | 否 | 是否生成声音。仅部分模型支持(如 Veo 3.1),会影响价格。 |
| negative_prompt | string | 否 | 需要避免的内容,最多 2000 个字符。 |
| image_urls | string 数组 | 否 | 参考图的公开地址,数量不超过模型上限。只支持一张的模型会把它用作起始帧。 |
任务所需的积分在提交时预扣,准确数额通过 credits_charged 返回。
创建图片
POST /images
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| model | string | 是 | 图片模型 ID,例如 nano-banana-2。 |
| prompt | string | 是 | 要生成的内容,1 到 4000 个字符。 |
| resolution | string | 否 | 例如 1K、2K,默认使用模型的默认值。 |
| aspect_ratio | string | 否 | 例如 1:1、16:9,默认使用模型的默认值。 |
| image_urls | string 数组 | 否 | 用于编辑或作为参考的图片公开地址,数量不超过模型上限。 |
curl -X POST https://apicafe.ai/api/v1/images \
-H "Authorization: Bearer sk-..." \
-H "Content-Type: application/json" \
-d '{"model": "nano-banana-2", "prompt": "A red apple on a white table, photorealistic"}'
部分图片模型会立刻出结果:返回的任务可能已经是 succeeded。请始终读取 status,不要想当然。
OpenAI 兼容的图片接口
已经在用 OpenAI 图片 API?把客户端的 base URL 指向下面这个地址,换成你的 API Key,其他都不用改。
POST /images/generations
from openai import OpenAI
client = OpenAI(base_url="https://apicafe.ai/api/v1", api_key="sk-...")
result = client.images.generate(
model="nano-banana-2",
prompt="A red apple on a white table, photorealistic",
size="1024x1024",
)
print(result.data[0].url)
| 字段 | 说明 |
|---|---|
| model | 图片模型 ID,见模型列表。 |
| prompt | 必填。 |
| size | 可选。会映射到该模型支持的最接近的画面比例和分辨率档位(1024x1024 是最低档的正方形,1792x1024 是 2K 横版,以此类推)。省略或用 auto 表示使用模型默认值。 |
| n | 只支持 1。 |
| response_format | 只支持 url。 |
调用会等待图片生成完成(最多约 50 秒),返回 {"created": ..., "data": [{"url": "..."}], "id": "...", "credits_charged": ...}。如果超过等待时间,会返回 504 generation_timeout,消息里带有任务 ID,用 GET /images/{id} 查询即可。积分保持预扣状态,生成失败会自动退回。
查询任务
GET /videos/{id} 和 GET /images/{id}
返回同样的任务对象。只能查询自己的任务,视频任务 ID 在图片接口上查不到(反之亦然)。
| 字段 | 说明 |
|---|---|
| id | 任务 ID。 |
| object | video.task 或 image.task。 |
| model | 使用的模型。 |
| status | processing、succeeded 或 failed。 |
| video_url | 仅视频任务。生成好的视频地址,succeeded 之前为 null。 |
| image_url | 仅图片任务。生成好的图片地址,succeeded 之前为 null。 |
| error | status 为 failed 时的简短原因,否则为 null。 |
| credits_charged | 该任务预扣的积分,任务失败时自动退回。 |
| created_at | 任务创建时间(ISO 8601)。 |
| completed_at | 任务完成时间,未完成为 null。 |
生成好的文件会复制到我们的存储。需要长期保存的内容,请自行下载备份。
模型列表
GET /models(无需认证)。加上 ?type=video 或 ?type=image 可以筛选。
返回可用模型的接口地址、限制,以及 pricing 列表(每种分辨率的 credits_per_unit,价格与声音相关的模型还会区分有声和无声)。unit 表示一个价格对应的单位:一秒视频(second)或一张图片(image)。这份列表始终是最新的。
价格与积分
- 1 积分 = 0.01 美元。
- 视频按生成的秒数计价,图片按张计价。价格取决于模型、分辨率,部分模型还取决于是否有声。
- 积分在提交任务时预扣;任务失败、被中断或超时,会自动退回。
- 一个视频任务的积分花费不会超过 credits_per_unit 乘以 duration,因四舍五入可能略低。
调用频率限制
每个 API Key 每 10 秒最多 20 次请求。超出会返回 429 rate_limited 和 Retry-After 请求头。轮询也计入限额,请每隔几秒轮询一次,不要连续高频请求。
错误
错误统一使用同一种结构:
{
"error": {
"code": "insufficient_credits",
"message": "This request costs 263 credits. Top up your balance and retry."
}
}
| HTTP | 错误码 | 含义 |
|---|---|---|
| 400 | invalid_json | 请求体不是合法的 JSON。 |
| 400 | invalid_request | 字段缺失、类型不对,或该模型不支持这个字段。 |
| 400 | invalid_duration | duration 超出该模型接受的范围。 |
| 400 | invalid_resolution | 该模型不支持这个 resolution。 |
| 400 | invalid_aspect_ratio | 该模型不支持这个 aspect_ratio。 |
| 400 | content_policy | 提示词被内容策略拒绝,不会扣费。 |
| 400 | too_many_images | 参考图数量超过模型上限。 |
| 401 | missing_api_key | 缺少 Authorization 请求头。 |
| 401 | invalid_api_key | Key 不存在或已被撤销。 |
| 401 | api_key_expired | Key 已过有效期。 |
| 402 | insufficient_credits | 余额不足以支付该任务。 |
| 402 | key_limit_exceeded | 会超出该 Key 自己的额度上限。 |
| 403 | account_suspended | 账户已被停用。 |
| 403 | ip_not_allowed | 该 Key 限制了可使用的 IP 地址。 |
| 403 | model_not_allowed | 该 Key 不允许使用这个模型。 |
| 404 | model_not_found | 模型不存在、已下线,或属于另一种媒体类型。 |
| 404 | task_not_found | 任务不存在。 |
| 429 | rate_limited | 请求过于频繁。 |
| 502 | upstream_error | 生成服务暂时不可用,不会扣费。 |
| 500 | internal_error | 我们这边出了问题,请重试。 |
示例
Python
import time
import requests
API = "https://apicafe.ai/api/v1"
HEADERS = {"Authorization": "Bearer sk-..."}
task = requests.post(
f"{API}/videos",
headers=HEADERS,
json={"model": "seedance-2.5", "prompt": "A red paper boat on a pond"},
).json()
while task["status"] == "processing":
time.sleep(5)
task = requests.get(f"{API}/videos/{task['id']}", headers=HEADERS).json()
print(task["status"], task.get("video_url") or task["error"])
JavaScript
const API = "https://apicafe.ai/api/v1";
const headers = {
Authorization: "Bearer sk-...",
"Content-Type": "application/json",
};
let task = await (
await fetch(`${API}/images`, {
method: "POST",
headers,
body: JSON.stringify({
model: "nano-banana-2",
prompt: "A red apple on a white table",
}),
})
).json();
while (task.status === "processing") {
await new Promise((resolve) => setTimeout(resolve, 3000));
task = await (await fetch(`${API}/images/${task.id}`, { headers })).json();
}
console.log(task.status, task.image_url ?? task.error);