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

字段类型必填说明
modelstring是视频模型 ID,例如 seedance-2.5。见模型列表。
promptstring是要生成的内容,1 到 4000 个字符。
durationinteger否时长(秒)。每个模型接受自己的范围或固定取值,默认使用模型的默认值。
resolutionstring否例如 720p,默认使用模型的默认值。
aspect_ratiostring否例如 16:9,默认使用模型的默认值。
audioboolean否是否生成声音。仅部分模型支持(如 Veo 3.1),会影响价格。
negative_promptstring否需要避免的内容,最多 2000 个字符。
image_urlsstring 数组否参考图的公开地址,数量不超过模型上限。只支持一张的模型会把它用作起始帧。

任务所需的积分在提交时预扣,准确数额通过 credits_charged 返回。

创建图片

POST /images

字段类型必填说明
modelstring是图片模型 ID,例如 nano-banana-2。
promptstring是要生成的内容,1 到 4000 个字符。
resolutionstring否例如 1K、2K,默认使用模型的默认值。
aspect_ratiostring否例如 1:1、16:9,默认使用模型的默认值。
image_urlsstring 数组否用于编辑或作为参考的图片公开地址,数量不超过模型上限。
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。
objectvideo.task 或 image.task。
model使用的模型。
statusprocessing、succeeded 或 failed。
video_url仅视频任务。生成好的视频地址,succeeded 之前为 null。
image_url仅图片任务。生成好的图片地址,succeeded 之前为 null。
errorstatus 为 failed 时的简短原因,否则为 null。
credits_charged该任务预扣的积分,任务失败时自动退回。
created_at任务创建时间(ISO 8601)。
completed_at任务完成时间,未完成为 null。

生成好的文件会复制到我们的存储。需要长期保存的内容,请自行下载备份。

模型列表

GET /models(无需认证)。加上 ?type=video 或 ?type=image 可以筛选。

返回可用模型的接口地址、限制,以及 pricing 列表(每种分辨率的 credits_per_unit,价格与声音相关的模型还会区分有声和无声)。unit 表示一个价格对应的单位:一秒视频(second)或一张图片(image)。这份列表始终是最新的。

价格与积分

调用频率限制

每个 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错误码含义
400invalid_json请求体不是合法的 JSON。
400invalid_request字段缺失、类型不对,或该模型不支持这个字段。
400invalid_durationduration 超出该模型接受的范围。
400invalid_resolution该模型不支持这个 resolution。
400invalid_aspect_ratio该模型不支持这个 aspect_ratio。
400content_policy提示词被内容策略拒绝,不会扣费。
400too_many_images参考图数量超过模型上限。
401missing_api_key缺少 Authorization 请求头。
401invalid_api_keyKey 不存在或已被撤销。
401api_key_expiredKey 已过有效期。
402insufficient_credits余额不足以支付该任务。
402key_limit_exceeded会超出该 Key 自己的额度上限。
403account_suspended账户已被停用。
403ip_not_allowed该 Key 限制了可使用的 IP 地址。
403model_not_allowed该 Key 不允许使用这个模型。
404model_not_found模型不存在、已下线,或属于另一种媒体类型。
404task_not_found任务不存在。
429rate_limited请求过于频繁。
502upstream_error生成服务暂时不可用,不会扣费。
500internal_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);