Submitting a task
视频是这个平台上唯一一种不是请求即响应的调用模式。你提交一个任务,立即拿到一个标识符,稍后再来收取结果。没有流式变体,也没有阻塞变体 —— 轮询是得知结果的唯一方式。
1import os, requests23response = requests.post(4 "https://www.realrelay.ai/v1/video/generations",5 headers={"Authorization": f"Bearer {os.environ['REALRELAY_API_KEY']}"},6 json={7 "model": "alibaba/wan2.1-t2v-plus",8 "prompt": "A paper boat drifting down a rain gutter",9 "duration": 5,10 },11)1213task_id = response.json()["task_id"]14print(task_id)1const response = await fetch("https://www.realrelay.ai/v1/video/generations", {2 method: "POST",3 headers: {4 Authorization: `Bearer ${process.env.REALRELAY_API_KEY}`,5 "Content-Type": "application/json",6 },7 body: JSON.stringify({8 model: "alibaba/wan2.1-t2v-plus",9 prompt: "A paper boat drifting down a rain gutter",10 duration: 5,11 }),12});1314const { task_id } = await response.json();15console.log(task_id);1curl https://www.realrelay.ai/v1/video/generations \2 -H "Authorization: Bearer $REALRELAY_API_KEY" \3 -H "Content-Type: application/json" \4 -d '{5 "model": "alibaba/wan2.1-t2v-plus",6 "prompt": "A paper boat drifting down a rain gutter",7 "duration": 58 }'910# {"task_id": "task_9f2c...", "status": "queued"}duration、width、
height、fps、
seed 和 image(一个 URL 或 base64 帧,用于图生视频模型)都被接受,而
metadata 会原样携带厂商特定的字段。某个模型接受哪些时长和分辨率因模型而异,并由提供方强制执行,因此不受支持的组合会让提交失败,而不是让任务失败。
Polling for status
你拿回的 task_id 是我们的,不是提供方的。请在你提交时所用的同一路径上轮询它:
1import os, time, requests23task_id = "task_9f2c..."4headers = {"Authorization": f"Bearer {os.environ['REALRELAY_API_KEY']}"}56while True:7 task = requests.get(8 f"https://www.realrelay.ai/v1/video/generations/{task_id}",9 headers=headers,10 ).json()1112 if task["status"] in ("completed", "failed"):13 break1415 time.sleep(10)1617if task["status"] == "failed":18 raise RuntimeError(task["error"]["message"])1920print(task["url"], task["format"])1const task_id = "task_9f2c...";2const headers = {3 Authorization: `Bearer ${process.env.REALRELAY_API_KEY}`,4};56let task;7do {8 await new Promise((resolve) => setTimeout(resolve, 10_000));9 const response = await fetch(10 `https://www.realrelay.ai/v1/video/generations/${task_id}`,11 { headers },12 );13 task = await response.json();14} while (task.status !== "completed" && task.status !== "failed");1516if (task.status === "failed") throw new Error(task.error.message);1718console.log(task.url, task.format);1curl https://www.realrelay.ai/v1/video/generations/task_9f2c... \2 -H "Authorization: Bearer $REALRELAY_API_KEY"34# in progress:5# {"task_id": "task_9f2c...", "status": "in_progress"}67# finished:8# {9# "task_id": "task_9f2c...",10# "status": "completed",11# "url": "https://...",12# "format": "mp4",13# "metadata": { "duration": 5, "fps": 30, "width": 1280, "height": 720 }14# }1516# failed:17# {"task_id": "task_9f2c...", "status": "failed",18# "error": { "code": 500, "message": "..." }}status 会经历
queued → in_progress →
completed,或者终止于
failed。请以秒为间隔轮询,而不是毫秒:生成需要多久取决于提供方,轮询得更频繁并不会让它更快完成。
Fetching the result
已完成的任务携带一个 url、一个
format,以及一个 metadata
块,描述实际生产出来的内容 —— 真实的时长、帧率和尺寸,这些可能与你所请求的不同。
1{2"task_id": "task_9f2c...",3"status": "completed",4"url": "https://...",5"format": "mp4",6"metadata": { "duration": 5, "fps": 30, "width": 1280, "height": 720 }7}不要把那个 URL 当作持久可用。它可能指向我们自己的代理、直接指向提供方,或者是一个内联的 data: 载荷,取决于模型 —— 而在前两种情况下它会过期。请在任务完成时下载文件,并自行存储。
Billing and failures
视频按调用计费,并按你实际生成的内容进行调整:时长和分辨率都是价格的一部分。提交时会先记一笔费用,任务结束时再结算,因此最终金额可能与提交时的估算不同。
以
failed结束的任务会被自动退款。你无需申请。在平台任务超时时间内 —— 默认 24 小时 —— 仍未完成的任务会被标记为
failed,并按同一规则退款。任务绝不会被永远挂起。只提交而从不轮询,仍然要向你收费:无论你是否收取结果,工作都会照常运行并结算。
每个模型的价格都在目录上。
