curl --request GET \
--url https://apis.viggle.ai/v1/videos/{video_id} \
--header 'Authorization: Bearer <token>'import requests
url = "https://apis.viggle.ai/v1/videos/{video_id}"
headers = {"Authorization": "Bearer <token>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
fetch('https://apis.viggle.ai/v1/videos/{video_id}', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://apis.viggle.ai/v1/videos/{video_id}",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://apis.viggle.ai/v1/videos/{video_id}"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("Authorization", "Bearer <token>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://apis.viggle.ai/v1/videos/{video_id}")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("https://apis.viggle.ai/v1/videos/{video_id}")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Bearer <token>'
response = http.request(request)
puts response.read_body{
"id": "<string>",
"status": "queued",
"stage": "queued",
"progress": 50,
"video_url": "<string>",
"alpha_url": "<string>",
"created_at": "2023-11-07T05:31:56Z",
"completed_at": "2023-11-07T05:31:56Z",
"error": {
"code": "UNAUTHENTICATED",
"message": "<string>",
"retryable": true,
"request_id": "<string>",
"details": {},
"remediation": {
"action": "<string>",
"retry_after_ms": 1
}
},
"seed": 123
}{
"error": {
"code": "UNAUTHENTICATED",
"message": "<string>",
"retryable": true,
"request_id": "<string>",
"details": {},
"remediation": {
"action": "<string>",
"retry_after_ms": 1
}
}
}{
"error": {
"code": "UNAUTHENTICATED",
"message": "<string>",
"retryable": true,
"request_id": "<string>",
"details": {},
"remediation": {
"action": "<string>",
"retry_after_ms": 1
}
}
}{
"error": {
"code": "UNAUTHENTICATED",
"message": "<string>",
"retryable": true,
"request_id": "<string>",
"details": {},
"remediation": {
"action": "<string>",
"retry_after_ms": 1
}
}
}{
"error": {
"code": "UNAUTHENTICATED",
"message": "<string>",
"retryable": true,
"request_id": "<string>",
"details": {},
"remediation": {
"action": "<string>",
"retry_after_ms": 1
}
}
}{
"error": {
"code": "UNAUTHENTICATED",
"message": "<string>",
"retryable": true,
"request_id": "<string>",
"details": {},
"remediation": {
"action": "<string>",
"retry_after_ms": 1
}
}
}{
"error": {
"code": "UNAUTHENTICATED",
"message": "<string>",
"retryable": true,
"request_id": "<string>",
"details": {},
"remediation": {
"action": "<string>",
"retry_after_ms": 1
}
}
}获取视频
通过统一接口获取渲染、H3 视频生成或角色动画生成的完整状态。
curl --request GET \
--url https://apis.viggle.ai/v1/videos/{video_id} \
--header 'Authorization: Bearer <token>'import requests
url = "https://apis.viggle.ai/v1/videos/{video_id}"
headers = {"Authorization": "Bearer <token>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
fetch('https://apis.viggle.ai/v1/videos/{video_id}', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://apis.viggle.ai/v1/videos/{video_id}",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://apis.viggle.ai/v1/videos/{video_id}"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("Authorization", "Bearer <token>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://apis.viggle.ai/v1/videos/{video_id}")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("https://apis.viggle.ai/v1/videos/{video_id}")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Bearer <token>'
response = http.request(request)
puts response.read_body{
"id": "<string>",
"status": "queued",
"stage": "queued",
"progress": 50,
"video_url": "<string>",
"alpha_url": "<string>",
"created_at": "2023-11-07T05:31:56Z",
"completed_at": "2023-11-07T05:31:56Z",
"error": {
"code": "UNAUTHENTICATED",
"message": "<string>",
"retryable": true,
"request_id": "<string>",
"details": {},
"remediation": {
"action": "<string>",
"retry_after_ms": 1
}
},
"seed": 123
}{
"error": {
"code": "UNAUTHENTICATED",
"message": "<string>",
"retryable": true,
"request_id": "<string>",
"details": {},
"remediation": {
"action": "<string>",
"retry_after_ms": 1
}
}
}{
"error": {
"code": "UNAUTHENTICATED",
"message": "<string>",
"retryable": true,
"request_id": "<string>",
"details": {},
"remediation": {
"action": "<string>",
"retry_after_ms": 1
}
}
}{
"error": {
"code": "UNAUTHENTICATED",
"message": "<string>",
"retryable": true,
"request_id": "<string>",
"details": {},
"remediation": {
"action": "<string>",
"retry_after_ms": 1
}
}
}{
"error": {
"code": "UNAUTHENTICATED",
"message": "<string>",
"retryable": true,
"request_id": "<string>",
"details": {},
"remediation": {
"action": "<string>",
"retry_after_ms": 1
}
}
}{
"error": {
"code": "UNAUTHENTICATED",
"message": "<string>",
"retryable": true,
"request_id": "<string>",
"details": {},
"remediation": {
"action": "<string>",
"retry_after_ms": 1
}
}
}{
"error": {
"code": "UNAUTHENTICATED",
"message": "<string>",
"retryable": true,
"request_id": "<string>",
"details": {},
"remediation": {
"action": "<string>",
"retry_after_ms": 1
}
}
}GET /v1/videos/{video_id} 接受三类 ID,并返回当前持久化状态:角色与动作渲染任务的 render_ ID;H3 的 vid_ ID,来源包括文本、首帧、首尾帧或参考素材生成;以及使用 Viggle-Animate生成的 anim_ ID。每 3–5 秒轮询一次,直到进入终态。Render 来源的 ID 也支持监听渲染推送。
本接口替代已停用的 GET /v1/renders/{render_id}。
405 Method Not Allowed,而不是 404,因为该路径仍注册有其他方法。只有路径完全没有注册方法时才返回 404。如旧集成通过 404 判断接口已停用,请同时处理 405,或直接迁移到本接口。请求参数
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
video_id | string | 是 | 渲染、生成或视频列表接口返回的完整公开 ID:render_...、vid_... 或 anim_...。使用同一 ID 每 3–5 秒轮询,直到进入终态。 |
响应参数
返回200 OK 和 Video 对象。
| 字段 | 类型 | 始终返回 | 说明 |
|---|---|---|---|
id | string | 是 | 所请求的视频 ID。 |
status | string | 是 | queued、processing、ready、failed 或 cancelled。 |
stage | string 或 null | 是 | 仅 Render 来源且 status=processing 时有值,其他情况为 null;H3 始终为 null。不存在 stage: "ready"。 |
progress | integer 或 null | 是 | 0–100 的进度,或 null。 |
video_url | string 或 null | 是 | 就绪后的输出下载地址;此前为 null。 |
alpha_url | string 或 null | 是 | 仅透明背景(background_mode=transparent)的 Render 在就绪后有值。H3 始终为 null。 |
created_at | string 或 null | 是 | Render 来源时间戳精确到纳秒;H3 来源精确到秒。 |
completed_at | string 或 null | 是 | 见下方完成时间说明。 |
error | object 或 null | 是 | status=failed 时的结构化错误详情。 |
seed | integer | 仅 H3 | 实际使用的随机种子:传入时原样返回,未传入时返回生成的值。仅 vid_ 视频包含该字段;Render 来源会省略此字段,而非返回 null。 |
links,因此不包含创建渲染响应中的 self、events、download 快捷链接。继续查询时使用同一 video_id;Render 来源的 ID 还可使用下载渲染结果。
完成时间
Render 来源的视频在status 变为 ready 后,completed_at 可能延迟约 30 秒回填,并非永久缺失。判断视频是否完成,应检查 status == "ready" 或 video_url 是否有值,不应依赖 completed_at 非空。
Render 来源示例
{
"id": "render_a1b2c3",
"status": "ready",
"stage": null,
"progress": 100,
"video_url": "https://assets.viggle.ai/render_a1b2c3.mp4",
"alpha_url": null,
"created_at": "2026-08-25T09:12:03.123456789Z",
"completed_at": "2026-08-25T09:13:47Z",
"error": null
}
H3 来源示例
{
"id": "vid_3f2a9c",
"status": "ready",
"stage": null,
"progress": 100,
"video_url": "https://storage.googleapis.com/...signed...",
"alpha_url": null,
"created_at": "2026-08-24T09:12:03Z",
"completed_at": "2026-08-24T09:13:47Z",
"error": null,
"seed": 4271960385017522688
}
角色动画来源示例
{
"id": "anim_7c1e4b",
"status": "ready",
"stage": null,
"progress": 100,
"video_url": "https://storage.googleapis.com/...signed...",
"alpha_url": null,
"created_at": "2026-09-09T09:12:03Z",
"completed_at": "2026-09-09T09:13:47Z",
"error": null
}
seed 字段;该字段仅适用于 H3。
失败示例
{
"id": "render_a1b2c3",
"status": "failed",
"stage": null,
"progress": null,
"video_url": null,
"alpha_url": null,
"created_at": "2026-08-25T09:12:03.123456789Z",
"completed_at": "2026-08-25T09:13:50Z",
"error": {
"code": "TASK_FAILED",
"message": "The render could not be completed.",
"retryable": false,
"request_id": "req_123abc",
"details": {},
"remediation": { "action": "contact_support", "retry_after_ms": null }
}
}
示例
curl "https://apis.viggle.ai/v1/videos/render_a1b2c3" -H "Authorization: Bearer $VIGGLE_API_KEY"
import os, requests
response = requests.get("https://apis.viggle.ai/v1/videos/render_a1b2c3", headers={"Authorization": f"Bearer {os.environ['VIGGLE_API_KEY']}"})
response.raise_for_status()
video = response.json()
const response = await fetch("https://apis.viggle.ai/v1/videos/render_a1b2c3", { headers: { Authorization: `Bearer ${process.env.VIGGLE_API_KEY}` } });
const video = await response.json();
req, _ := http.NewRequest("GET", "https://apis.viggle.ai/v1/videos/render_a1b2c3", nil)
req.Header.Set("Authorization", "Bearer "+os.Getenv("VIGGLE_API_KEY"))
resp, err := http.DefaultClient.Do(req)
if err != nil { panic(err) }
defer resp.Body.Close()
授权
服务端 SDK 使用项目 API 密钥,Remote MCP 使用 OAuth 访问令牌。不要在浏览器代码中暴露项目密钥。
请求头
可选的调用者自定义关联 ID,最长 128 字符。服务会在响应头返回实际使用的值,便于追踪和支持排查。
1 - 128可选来源标签,最长 128 字符,用于识别 SDK、集成、产品入口或内部工作流。
1 - 128路径参数
当前调用者拥有的视频公开 ID:渲染为 render_,H3 为 vid_,角色动画为 anim_。
1响应
请求成功。
统一、只读的视频完整状态,支持 render_、vid_ 和 anim_。不包含 links 或 self/events/download 快捷链接。stage 仅 Render 来源且 processing 时有值,其余为 null。alpha_url 仅透明背景 Render 就绪时有值。seed 仅 H3 包含,Render 和角色动画完全省略该字段,而不是返回 null。
所请求的视频 ID。
1queued、processing、ready、failed 或 cancelled。
queued, processing, ready, failed, cancelled 仅 Render 来源且 status=processing 时有值,其他情况为 null;H3 始终为 null。不存在 stage: "ready"。
queued, preparing, generating, finalizing, ready, failed, cancelled, analyzing, rendering, finishing 0–100 的进度,或 null。
0 <= x <= 100就绪后的输出下载地址;此前为 null。
仅透明背景(background_mode=transparent)的 Render 在就绪后有值。H3 始终为 null。
Render 来源时间戳精确到纳秒;H3 来源精确到秒。
见下方完成时间说明。
status=failed 时的结构化错误详情。
Show child attributes
Show child attributes
实际使用的随机种子:传入时原样返回,未传入时返回生成的值。仅 vid_ 视频包含该字段;Render 来源会省略此字段,而非返回 null。

