APIMart 视频生成 API 怎么用?注册、轮询与下载完整教程
简答:APIMart 视频生成 API 的最短闭环是:注册账户并准备点数→创建 API Key→用 Bearer Token 调用 <code>POST /v1/videos/generations</code>→保存返回的 <code>task_id</code>→调用 <code>GET /v1/tasks/{task_id}</code> 查询进度。提交接口和任务查询接口已在公开文档中出现,但请求字段、完成状态和视频结果字段要以所选模型页面及实际响应为准。你最终要拿到的是:<strong>task_id → 任务状态 → 视频 URL → 本地 MP4 文件</strong>。
定义:APIMart 视频生成 API 是一种通过 HTTP 提交视频生成任务、异步查询任务状态,并在任务完成后取得结果地址的 API 调用方式。
先复制这条链路:注册、Key、提交、轮询、下载
本文是站内第三方接入指南,不是 APIMart 官方页面。APIMart 快速上手文档将首次调用拆分为创建账户、购买点数、创建 API 密钥和完成调用四步;文档还说明 API Key 通过 Authorization: Bearer ... 发送。可先查看快速上手文档中的账户、点数和密钥说明。
| 步骤 | 执行内容 | 成功判定 |
|---|---|---|
| 1 | 打开注册页面创建账户,并确认账户有可用点数 | 可以进入控制台并查看账户状态 |
| 2 | 在 API Key 页面创建密钥,保存到服务端环境变量 | 请求头可写成 Authorization: Bearer YOUR_API_KEY |
| 3 | 向 https://api.apimart.ai/v1/videos/generations 发送 POST 请求 | 以所选模型文档为准;Kling v3 示例返回 task_id |
| 4 | 调用 GET https://api.apimart.ai/v1/tasks/<TASK_ID> | 拿到任务状态或结果;该路径来自任务状态文档 |
| 5 | 从实际响应中提取视频地址并下载 | 本地文件可打开,且响应的 Content-Type 与文件类型匹配 |
重要边界:Kling v3 视频生成文档明确给出了视频提交地址、Bearer 鉴权、task_id 返回示例和模型参数;这不代表所有视频模型都使用完全相同的字段。任务查询地址和查询示例见Get Task Status 文档。
注册账户、购买点数并创建 API Key
- 根据APIMart 快速上手页面,进入账户注册页面,使用邮箱和密码创建账户,或按照页面显示选择 Google 身份登录。注册入口、验证要求和页面布局可能调整,实际以当前控制台为准。
- 登录后打开控制台的 API 密钥页面,创建一个便于识别用途的名称,例如
video-test。快速上手文档列出的路径是“API 密钥页面”,不要把注册密码、账户 ID 或模型名当作 API Key。 - 创建后立即复制完整密钥。该文档说明完整密钥只显示一次,之后面板显示掩码版本;密钥示例形如
apmart_...,但不要自行拼接或猜测 Key。 - 调用前确认点数和当前模型价格。快速上手文档说明该服务按预付费点数调用,并提示在调用前查看目录或面板中的单次价格;本文不据此推断任何具体视频模型的实际费用。
建议把密钥放在后端环境变量中,例如 APIMART_API_KEY。不要把真实 Key 写入浏览器前端、公开代码仓库、截图或未脱敏日志;如果已经泄露,应先在控制台轮换或吊销。
可复制的提交请求:先用 Kling v3 文生视频验证
下面只使用当前可访问的 Kling v3 模型文档作为具体示例。文档列出的提交地址是 POST https://api.apimart.ai/v1/videos/generations,示例字段包括 model、prompt、mode、duration 和 aspect_ratio。这些字段属于 Kling v3 示例,不要直接套到其他视频模型。
cURL:
curl --request POST --url https://api.apimart.ai/v1/videos/generations --header "Authorization: Bearer YOUR_API_KEY" --header "Content-Type: application/json" --data "{\"model\":\"kling-v3\",\"prompt\":\"A golden cat running on a sunlit meadow, slow motion, cinematic quality\",\"mode\":\"std\",\"duration\":5,\"aspect_ratio\":\"16:9\"}"
Kling v3 文档给出的提交成功示例包含 code: 200、data 数组、status: submitted 和 task_id。这里是该模型页面的示例响应,不应当作所有视频模型的统一响应规范。
Python 提交:
import os, requests
API_KEY = os.environ["APIMART_API_KEY"]
url = "https://api.apimart.ai/v1/videos/generations"
payload = {"model": "kling-v3", "prompt": "A golden cat running on a sunlit meadow, slow motion, cinematic quality", "mode": "std", "duration": 5, "aspect_ratio": "16:9"}
r = requests.post(url, headers={"Authorization": f"Bearer {API_KEY}", "Content-Type": "application/json"}, json=payload, timeout=60)
r.raise_for_status()
body = r.json()
task_id = body.get("data", [{}])[0].get("task_id")
if not task_id: raise RuntimeError(f"未找到 task_id:{body}")
print(task_id)
JavaScript 提交:
const apiKey = process.env.APIMART_API_KEY;
const response = await fetch("https://api.apimart.ai/v1/videos/generations", {method:"POST", headers:{"Authorization":`Bearer ${apiKey}`,"Content-Type":"application/json"}, body:JSON.stringify({model:"kling-v3",prompt:"A golden cat running on a sunlit meadow, slow motion, cinematic quality",mode:"std",duration:5,aspect_ratio:"16:9"})});
const body = await response.json();
if (!response.ok) throw new Error(JSON.stringify(body));
const taskId = body?.data?.[0]?.task_id;
if (!taskId) throw new Error(`未找到 task_id:${JSON.stringify(body)}`);
console.log(taskId);
完整轮询与下载:Python 示例
任务状态文档公开了 GET /v1/tasks/{task_id} 形式,并给出了 Python 查询示例;Kling v3 文档说明视频生成是异步任务,提交后要使用任务状态接口查询进度和结果。下面代码加入总超时、指数退避、失败分支和下载逻辑。由于当前 Kling v3 页面没有展示完整的视频完成响应 JSON,代码采用递归查找常见 URL 字段的兼容写法;若实际响应字段不同,应先打印脱敏后的 JSON,再按模型文档修改 find_url。
Python 闭环代码:
import os, time, requests
API_KEY = os.environ["APIMART_API_KEY"]
BASE = "https://api.apimart.ai"
HEADERS = {"Authorization": f"Bearer {API_KEY}"}
payload = {
"model": "kling-v3",
"prompt": "A golden cat running on a sunlit meadow, slow motion, cinematic quality",
"mode": "std",
"duration": 5,
"aspect_ratio": "16:9"
}
submit = requests.post(f"{BASE}/v1/videos/generations", headers={**HEADERS, "Content-Type":"application/json"}, json=payload, timeout=60)
submit.raise_for_status()
submitted = submit.json()
task_id = submitted.get("data", [{}])[0].get("task_id")
if not task_id:
raise RuntimeError(f"提交响应没有 task_id:{submitted}")
def find_url(value):
if isinstance(value, dict):
for key in ("video_url", "video_urls", "url", "urls"):
candidate = value.get(key)
if isinstance(candidate, str) and candidate.startswith(("http://", "https://")): return candidate
if isinstance(candidate, list):
for item in candidate:
if isinstance(item, str) and item.startswith(("http://", "https://")): return item
for item in value.values():
found = find_url(item)
if found: return found
elif isinstance(value, list):
for item in value:
found = find_url(item)
if found: return found
return None
deadline = time.monotonic() + 900
delay = 2
terminal_failures = {"failed", "error", "cancelled", "canceled"}
while time.monotonic() < deadline:
check = requests.get(f"{BASE}/v1/tasks/{task_id}", headers=HEADERS, params={"language":"en"}, timeout=30)
check.raise_for_status()
body = check.json()
data = body.get("data") if isinstance(body, dict) else None
status = data.get("status") if isinstance(data, dict) else None
print("status:", status)
if status in terminal_failures:
raise RuntimeError(f"任务失败:{body}")
url = find_url(body) if status in {"completed", "succeeded", "success"} else None
if url:
video = requests.get(url, timeout=120)
video.raise_for_status()
with open("output.mp4", "wb") as f: f.write(video.content)
print("已保存 output.mp4")
break
time.sleep(delay)
delay = min(delay * 1.5, 20)
else:
raise TimeoutError("超过总等待时间,保留 task_id 后稍后查询:" + task_id)
代码中的 completed、succeeded 和 URL 字段是兼容处理分支,不是对所有视频模型状态名称的统一声明。实际接入时,应优先以任务响应中的状态和值为准;如果完成后没有找到 URL,不要反复提交任务,先保存原始响应并核对当前模型页面。
JavaScript 闭环示例:提交、轮询、下载到文件
下面示例适用于 Node.js 18 或更高版本,使用内置 fetch 和文件系统模块。它同样把结果字段处理写成兼容函数,因为当前已核验资料明确了任务查询接口,但没有给出所有视频模型统一的视频结果 JSON。
import fs from "node:fs/promises";
const key = process.env.APIMART_API_KEY;
const base = "https://api.apimart.ai";
const headers = {"Authorization":`Bearer ${key}`,"Content-Type":"application/json"};
const submitRes = await fetch(`${base}/v1/videos/generations`, {method:"POST", headers, body:JSON.stringify({model:"kling-v3", prompt:"A golden cat running on a sunlit meadow, slow motion, cinematic quality", mode:"std", duration:5, aspect_ratio:"16:9"})});
const submit = await submitRes.json();
if (!submitRes.ok) throw new Error(JSON.stringify(submit));
const taskId = submit?.data?.[0]?.task_id;
if (!taskId) throw new Error(`提交响应没有 task_id:${JSON.stringify(submit)}`);
function findUrl(value) {
if (Array.isArray(value)) { for (const item of value) { const found = findUrl(item); if (found) return found; } }
if (value && typeof value === "object") {
for (const key of ["video_url","video_urls","url","urls"]) {
const item = value[key];
if (typeof item === "string" && /^https?:\/\//.test(item)) return item;
if (Array.isArray(item)) { const found = item.find(x => typeof x === "string" && /^https?:\/\//.test(x)); if (found) return found; }
}
for (const item of Object.values(value)) { const found = findUrl(item); if (found) return found; }
}
return null;
}
const deadline = Date.now() + 15 * 60 * 1000;
let delay = 2000;
while (Date.now() < deadline) {
const res = await fetch(`${base}/v1/tasks/${encodeURIComponent(taskId)}?language=en`, {headers:{"Authorization":`Bearer ${key}`}});
const body = await res.json();
if (!res.ok) throw new Error(JSON.stringify(body));
const data = body?.data;
const status = data?.status;
console.log("status:", status);
if (["failed","error","cancelled","canceled"].includes(status)) throw new Error(`任务失败:${JSON.stringify(body)}`);
const url = ["completed","succeeded","success"].includes(status) ? findUrl(body) : null;
if (url) {
const videoRes = await fetch(url);
if (!videoRes.ok) throw new Error(`下载失败:HTTP ${videoRes.status}`);
await fs.writeFile("output.mp4", Buffer.from(await videoRes.arrayBuffer()));
console.log("已保存 output.mp4");
break;
}
await new Promise(resolve => setTimeout(resolve, delay));
delay = Math.min(Math.floor(delay * 1.5), 20000);
}
如果你采用其他模型,只替换提交请求中的模型名和模型专属字段,并重新核对该模型页面;不要仅因为提交路径相同,就假定参数、状态名或结果结构相同。
模型选择与参数核对:统一的是流程,不是请求体
| 需求 | 当前资料中可确认的示例 | 必须核对的内容 |
|---|---|---|
| 文字生成视频 | Kling v3 使用 prompt,并可搭配 mode、duration、aspect_ratio | 模型 ID、时长范围、画质模式、比例和音频字段 |
| 图片生成视频 | Kling v3 文档列出 image_urls,并说明无图片时为文生视频、有图片时为图生视频 | 图片数量、URL 可访问性、图片比例是否覆盖请求比例 |
| 首帧或首尾帧 | Kling v3 文档示例使用 1 张或 2 张 image_urls | 当前模型是否支持首尾帧,以及两张图片的顺序含义 |
| 音频 | Kling v3 文档示例列出 audio: true | 是否产生额外费用、支持的模式和当前模型限制 |
| 其他视频模型 | 需打开对应模型页面确认 | 不要把 Kling v3 字段复制到 Seedance、Wan、PixVerse 或其他模型 |
Kling v3 页面还列出了文生视频、图生视频、首帧、首尾帧和音频示例,并说明视频任务采用异步处理。模型名称、字段和能力会随文档更新;截至 2026 年 11 月 1 日,本文只把当前可访问页面中明确出现的 Kling v3 字段作为具体示例,其他模型信息需重新核对。
401、402、404、429、5xx 与超时排查
| 现象 | 资料中可确认或建议核对的方向 | 下一步 |
|---|---|---|
| 401 | Kling v3 文档示例将其描述为认证凭据无效 | 检查 Key 是否完整、Bearer 拼写是否正确、是否误用了已轮换的旧 Key |
| 402 | Kling v3 文档示例为余额不足提示 | 查看账户点数、当前模型价格和实际响应;不要只凭状态码猜测扣费规则 |
| 404 | 可能是提交路径、任务路径或 task_id 不匹配 | 提交用模型文档给出的路径;查询用任务状态文档的 /v1/tasks/{task_id} 形式,并确认 task_id 未被截断 |
| 429 | Kling v3 文档示例为速率限制提示 | 降低并发,使用指数退避,记录响应体和响应头;不要把 429 当成余额不足 |
| 400 | 文档示例为请求参数无效 | 逐项检查模型专属字段、字段类型、时长、比例和素材 URL |
| 500 或 502 | 文档示例分别对应服务端错误或网关暂时不可用 | 保存 task_id 和脱敏响应,短暂退避后查询;不要在不确定任务状态时盲目重复提交 |
| 客户端超时 | 提交和视频生成是两个阶段 | 提交请求设置合理 HTTP 超时,生成过程交给任务查询;同时检查 DNS、TLS、出口防火墙和代理 |
排错顺序建议固定为:确认凭据→确认 Base URL 和路径→确认模型 ID→发最小请求→按 401/402/404/429/5xx 分流。每次记录请求方法、路径、模型、HTTP 状态码、脱敏响应和 task_id,绝不要记录完整 API Key。
常见问题
APIMart 视频生成 API 需要先注册吗?
需要。快速上手文档将创建账户、购买点数和创建 API Key 列为首次付费 API 调用前置步骤。注册页面和控制台布局以当前页面显示为准。
APIMart 视频 API 的提交地址是什么?
当前可访问的 Kling v3 文档使用 POST https://api.apimart.ai/v1/videos/generations。这是已核验模型页面中的视频提交地址;调用其他模型前仍应打开对应模型文档核对。
为什么提交后没有直接得到 MP4?
视频生成是异步流程。Kling v3 文档说明提交后返回 task_id,任务状态文档提供 GET /v1/tasks/{task_id} 查询形式。最终视频结果字段要以实际模型响应为准。
所有视频模型都使用相同参数吗?
不应这样假设。统一提交路径不等于请求体统一。本文仅核对了 Kling v3 的 mode、duration、aspect_ratio、image_urls 和 audio 等字段,其他模型必须逐页查看。
查询完成后如何下载视频?
从完成响应中读取实际返回的视频 URL,再用带超时和状态检查的 HTTP GET 下载到服务端或对象存储。当前核验资料没有提供所有视频模型统一的完成响应字段,因此示例代码采用兼容提取逻辑;如果没有找到 URL,应保存原始响应并按当前模型文档调整。
常见问题
APIMart 视频生成 API 需要先注册吗?
需要。首次调用前要创建账户、准备点数并创建 API Key,具体注册和控制台页面以当前服务显示为准。
APIMart 视频 API 的 Base URL 和提交地址是什么?
当前可访问的 Kling v3 文档使用 https://api.apimart.ai/ 作为 Base URL,提交路径为 /v1/videos/generations;其他模型仍需逐页核对。
task_id 查询路径可以固定写成 /v1/tasks/{id} 吗?
当前任务状态文档公开了 GET /v1/tasks/{task_id} 形式,但调用时仍应确认 task_id、鉴权和当前文档版本;不要把其他任务类型的字段结构直接套用。
为什么代码拿不到视频 URL?
当前核验资料明确了异步查询流程,但没有给出所有视频模型统一的完成响应结构。先打印脱敏后的查询 JSON,再按实际字段修改结果提取逻辑。
401、402、429 分别怎么处理?
401先检查 Bearer Key;402查看点数和当前模型价格;429降低并发并采用退避。具体错误信息以实际响应为准,不要只依据状态码推断全部平台规则。
相关阅读
- 先看 APIMart 注册、创建 Key 与首次调用流程
- 继续排查 API Key、Bearer 与 Base URL 导致的 401
- 了解 429 限流、配额与重试排查
- 查看 API 超时、轮询与异步任务处理方法
- 按聊天、图像和视频类型核对模型
参考资料
- APIMart 快速上手:创建账户、购买点数、创建 API 密钥与首次调用(apimart.app)
- APIMart Kling v3 视频生成 API:提交地址、参数、响应和异步任务说明(docs.apimart.ai)