Pense Video API 接入文档

使用 MX Canvas 账号中的积分调用视频生成能力。模型、价格、分辨率、时长和可见性均以后台实时配置为准。

Base URLhttps://api.pense.cn/v1

快速开始

1. 充值积分

登录 MX Canvas,在软件账号中充值积分。API 调用和软件生成共用同一积分余额。

2. 创建密钥

进入“个人信息 → API 接入”,创建并立即保存以 pense_sk_ 开头的密钥。

3. 获取模型

调用 GET /models,使用返回的完整模型 ID、时长和分辨率。

4. 提交并查询

提交视频任务获得任务 ID,再定时调用任务查询接口直到成功或失败。

身份认证

所有 /v1 接口都必须在请求头中携带 API Key:

Authorization: Bearer pense_sk_xxxxxxxxxxxxxxxxx
完整密钥只在创建时展示一次。不要放进前端网页、公开仓库或客户端日志;泄露后请立即在 MX Canvas 中禁用。

模型列表

GET/models

返回当前向用户开放并且已经设置价格的视频模型。务必使用返回的完整 id

与软件后台实时同步:后台视频模型管理中“向用户展示”的模型和分辨率,才会开放给 API 用户。隐藏模型不会出现在本列表中,即使手工提交隐藏模型 ID,服务端也会拒绝生成。
curl https://api.pense.cn/v1/models \
  -H "Authorization: Bearer pense_sk_xxx"
{
  "object": "list",
  "data": [{
    "id": "release/seedance-2.0",
    "object": "model",
    "name": "Seedance 2.0",
    "billing_mode": "per_generation",
    "credit_cost": 5.5,
    "resolution_prices": {},
    "config": {
      "video_generation": {
        "fixed_fields": {
          "duration": {"values": ["4", "5", "6"]},
          "resolution": {"values": ["480p", "720p"]}
        }
      }
    }
  }]
}

账户余额

GET/account/balance
curl https://api.pense.cn/v1/account/balance \
  -H "Authorization: Bearer pense_sk_xxx"
{
  "user_id": "用户ID",
  "credits": 120.5,
  "personal_credits": 80.5,
  "team_credits": 40
}

credits 是当前总可用积分。团队成员调用时,可按现有团队规则使用团长共享积分。

生成视频

POST/videos/generations
字段类型必填说明
modelstring/models 返回的完整 ID,例如 release/seedance-2.0
promptstring视频提示词,最长 4000 个字符
durationnumber时长秒数,必须使用该模型支持的值
ratiostring画面比例,例如 16:99:161:1
resolutionstring例如 480p720p1080p
referencesarray图生视频或多模态参考素材
extensionsobject模型扩展参数,以模型接口返回能力为准
curl https://api.pense.cn/v1/videos/generations \
  -H "Authorization: Bearer pense_sk_xxx" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "release/seedance-2.0",
    "prompt": "海边日出,镜头缓慢向前推进,电影感",
    "duration": 5,
    "ratio": "16:9",
    "resolution": "720p"
  }'
{
  "id": "task_xxxxxxxxx",
  "object": "video.task",
  "status": "accepted",
  "model": "release/seedance-2.0",
  "credit_cost": 5.5,
  "credits": 115
}

图生视频与参考素材

references 中传入可公开访问的 HTTPS 地址,或合法的 Base64 Data URL:

{
  "model": "aistartlab/模型ID",
  "prompt": "让人物自然转身并看向镜头",
  "duration": 5,
  "ratio": "9:16",
  "resolution": "720p",
  "references": [{
    "url": "https://example.com/reference.jpg",
    "kind": "image",
    "name": "reference.jpg",
    "mime": "image/jpeg"
  }]
}
不同上游模型支持的素材数量和类型不同。建议优先读取 /models 的模型配置,并控制素材文件大小。

穗禾首尾帧

/models 返回的穗禾模型配置中包含 config.video_generation.reference_modes,且其中有 first_last_frames 时,可以使用首尾帧。调用时把前两张图片放入 references,并传入 extensions.function_mode=first_last_frames。服务端会把第一张图片转为穗禾的 first_frame,第二张图片转为 end_frame

{
  "model": "shapi/穗禾模型ID",
  "prompt": "从首帧自然运动到尾帧,镜头平滑推进",
  "duration": 5,
  "ratio": "16:9",
  "resolution": "720p",
  "extensions": {
    "function_mode": "first_last_frames"
  },
  "references": [
    {
      "url": "https://example.com/start.jpg",
      "kind": "image",
      "name": "start.jpg",
      "mime": "image/jpeg"
    },
    {
      "url": "https://example.com/end.jpg",
      "kind": "image",
      "name": "end.jpg",
      "mime": "image/jpeg"
    }
  ]
}

查询任务

GET/videos/tasks/{task_id}
curl https://api.pense.cn/v1/videos/tasks/task_xxxxxxxxx \
  -H "Authorization: Bearer pense_sk_xxx"
{
  "id": "task_xxxxxxxxx",
  "object": "video.task",
  "status": "succeeded",
  "model": "release/seedance-2.0",
  "result": {
    "items": [{
      "kind": "video",
      "delivery_status": "ready",
      "download_url": "https://..."
    }]
  },
  "credits": 115,
  "refunded": false
}

常见状态:acceptedqueuedprocessingsucceededfailed。建议每 5 秒查询一次。

计费与退款

任务提交前由服务器计算并预扣积分。提交失败会立即退款;任务最终失败时会自动退款,成功任务不退款。
  • 按次计费:每次任务扣除后台设置的固定积分。
  • 按秒计费:每秒价格 × 用户选择时长,不进行整数四舍五入。
  • 不同分辨率可使用不同的每秒价格。
  • 没有设置价格或被后台隐藏的模型、分辨率无法调用。
  • 团队成员调用会记录实际调用用户,并按团队共享积分规则扣费。

状态码与错误

HTTP含义处理建议
200请求成功读取返回的 JSON 数据
400参数、模型、价格或余额问题读取响应中的 detail 并修正请求
401API Key 缺失、错误或已禁用检查 Authorization 请求头
403无权访问该任务任务只能由创建它的账号查询
404任务或资源不存在确认任务 ID 完整且正确
422请求体格式不正确检查字段类型和必填字段
429请求过于频繁降低频率,默认每个 Key 每分钟最多 60 次
502/504上游异常或超时稍后重试;失败任务按规则自动退款
{
  "detail": "错误原因"
}

代码示例

Python

import time
import requests

API_KEY = "pense_sk_xxx"
BASE_URL = "https://api.pense.cn/v1"
headers = {"Authorization": f"Bearer {API_KEY}"}

task = requests.post(
    f"{BASE_URL}/videos/generations",
    headers={**headers, "Content-Type": "application/json"},
    json={
        "model": "release/seedance-2.0",
        "prompt": "海边日出,电影感",
        "duration": 5,
        "ratio": "16:9",
        "resolution": "720p",
    },
    timeout=180,
).json()

while True:
    result = requests.get(
        f"{BASE_URL}/videos/tasks/{task['id']}",
        headers=headers,
        timeout=60,
    ).json()
    if result.get("status") in {"succeeded", "failed"}:
        print(result)
        break
    time.sleep(5)

JavaScript

const apiKey = "pense_sk_xxx";
const baseUrl = "https://api.pense.cn/v1";

const response = await fetch(`${baseUrl}/videos/generations`, {
  method: "POST",
  headers: {
    "Authorization": `Bearer ${apiKey}`,
    "Content-Type": "application/json"
  },
  body: JSON.stringify({
    model: "release/seedance-2.0",
    prompt: "海边日出,电影感",
    duration: 5,
    ratio: "16:9",
    resolution: "720p"
  })
});

const task = await response.json();
console.log(task);