VIGGLE_API_KEY,并将所有示例 ID 替换为自己账户返回的完整 ID。
积分 — GET /v1/credits
req, _ := http.NewRequest("GET", "https://apis.viggle.ai/v1/credits", nil)
req.Header.Set("Authorization", "Bearer "+os.Getenv("VIGGLE_API_KEY")); resp, _ := http.DefaultClient.Do(req)
const resp = await fetch("https://apis.viggle.ai/v1/credits", {headers:{Authorization:`Bearer ${process.env.VIGGLE_API_KEY}`}});
resp = requests.get("https://apis.viggle.ai/v1/credits", headers={"Authorization": f"Bearer {os.environ['VIGGLE_API_KEY']}"})
curl "https://apis.viggle.ai/v1/credits" -H "Authorization: Bearer $VIGGLE_API_KEY"
创建角色 — POST /v1/characters
body := &bytes.Buffer{}; w := multipart.NewWriter(body); f, _ := w.CreateFormFile("image", "character.png"); file, _ := os.Open("character.png"); io.Copy(f, file); w.WriteField("name", "Presenter"); w.Close()
req, _ := http.NewRequest("POST", "https://apis.viggle.ai/v1/characters", body); req.Header.Set("Authorization", "Bearer "+os.Getenv("VIGGLE_API_KEY")); req.Header.Set("Content-Type", w.FormDataContentType()); resp, _ := http.DefaultClient.Do(req)
const form = new FormData(); form.append("image", imageFile); form.append("name", "Presenter");
const resp = await fetch("https://apis.viggle.ai/v1/characters", {method:"POST", headers:{Authorization:`Bearer ${process.env.VIGGLE_API_KEY}`}, body:form});
with open("character.png", "rb") as image:
resp = requests.post("https://apis.viggle.ai/v1/characters", headers={"Authorization": f"Bearer {os.environ['VIGGLE_API_KEY']}"}, files={"image": image}, data={"name": "Presenter"})
curl -X POST "https://apis.viggle.ai/v1/characters" -H "Authorization: Bearer $VIGGLE_API_KEY" -F "[email protected]" -F "name=Presenter"
-F "type=vsplat" 提取 3D vsplat;同时保留渲染能力使用 all:
cURL
curl -X POST "https://apis.viggle.ai/v1/characters" -H "Authorization: Bearer $VIGGLE_API_KEY" -F "[email protected]" -F "type=vsplat"
列出、获取、删除和导出角色
req, _ := http.NewRequest("GET", "https://apis.viggle.ai/v1/characters/char_550e8400-e29b-41d4-a716-446655440000", nil); req.Header.Set("Authorization", "Bearer "+os.Getenv("VIGGLE_API_KEY")); resp, _ := http.DefaultClient.Do(req)
const resp = await fetch(`https://apis.viggle.ai/v1/characters/${characterId}`, {headers:{Authorization:`Bearer ${process.env.VIGGLE_API_KEY}`}});
resp = requests.get(f"https://apis.viggle.ai/v1/characters/{character_id}", headers={"Authorization": f"Bearer {os.environ['VIGGLE_API_KEY']}"})
curl "https://apis.viggle.ai/v1/characters" -H "Authorization: Bearer $VIGGLE_API_KEY"
curl "https://apis.viggle.ai/v1/characters/char_550e8400-e29b-41d4-a716-446655440000" -H "Authorization: Bearer $VIGGLE_API_KEY"
curl -X DELETE "https://apis.viggle.ai/v1/characters/char_550e8400-e29b-41d4-a716-446655440000" -H "Authorization: Bearer $VIGGLE_API_KEY"
curl "https://apis.viggle.ai/v1/characters/char_550e8400-e29b-41d4-a716-446655440000/export?download_type=vsplat" -H "Authorization: Bearer $VIGGLE_API_KEY"
GET /v1/characters;删除时将请求方法改为 DELETE。全部请求和响应字段见角色。
从视频创建动作 — POST /v1/motions
body := &bytes.Buffer{}; w := multipart.NewWriter(body); f, _ := w.CreateFormFile("motion_video", "dance.mp4"); file, _ := os.Open("dance.mp4"); io.Copy(f, file); w.WriteField("name", "Dance"); w.Close()
req, _ := http.NewRequest("POST", "https://apis.viggle.ai/v1/motions", body); req.Header.Set("Authorization", "Bearer "+os.Getenv("VIGGLE_API_KEY")); req.Header.Set("Content-Type", w.FormDataContentType()); resp, _ := http.DefaultClient.Do(req)
const form = new FormData(); form.append("motion_video", videoFile); form.append("name", "Dance");
const resp = await fetch("https://apis.viggle.ai/v1/motions", {method:"POST", headers:{Authorization:`Bearer ${process.env.VIGGLE_API_KEY}`}, body:form});
with open("dance.mp4", "rb") as video:
resp = requests.post("https://apis.viggle.ai/v1/motions", headers={"Authorization": f"Bearer {os.environ['VIGGLE_API_KEY']}"}, files={"motion_video": video}, data={"name": "Dance"})
curl -X POST "https://apis.viggle.ai/v1/motions" -H "Authorization: Bearer $VIGGLE_API_KEY" -F "[email protected]" -F "name=Dance"
-F "type=glb" 提取 3D 动画。
从文本创建动作 — POST /v1/motions
接口路径相同,文本生成动作使用 application/json,视频输入使用 multipart。
const resp = await fetch("https://apis.viggle.ai/v1/motions", {method:"POST", headers:{Authorization:`Bearer ${process.env.VIGGLE_API_KEY}`, "Content-Type":"application/json"}, body:JSON.stringify({text:"a person doing a cartwheel", duration_seconds:5})});
resp = requests.post("https://apis.viggle.ai/v1/motions", headers={"Authorization": f"Bearer {os.environ['VIGGLE_API_KEY']}"}, json={"text":"a person doing a cartwheel", "duration_seconds":5})
curl -X POST "https://apis.viggle.ai/v1/motions" -H "Authorization: Bearer $VIGGLE_API_KEY" -H "Content-Type: application/json" -d '{"text":"a person doing a cartwheel","duration_seconds":5}'
导入动作 — POST /v1/motions/import
body := strings.NewReader(`{"template_id":"YOUR_TEMPLATE_ID","name":"Campaign dance"}`); req, _ := http.NewRequest("POST", "https://apis.viggle.ai/v1/motions/import", body); req.Header.Set("Authorization", "Bearer "+os.Getenv("VIGGLE_API_KEY")); req.Header.Set("Content-Type", "application/json"); resp, _ := http.DefaultClient.Do(req)
const resp = await fetch("https://apis.viggle.ai/v1/motions/import", {method:"POST", headers:{Authorization:`Bearer ${process.env.VIGGLE_API_KEY}`, "Content-Type":"application/json"}, body:JSON.stringify({template_id:"YOUR_TEMPLATE_ID", name:"Campaign dance"})});
resp = requests.post("https://apis.viggle.ai/v1/motions/import", headers={"Authorization": f"Bearer {os.environ['VIGGLE_API_KEY']}"}, json={"template_id":"YOUR_TEMPLATE_ID", "name":"Campaign dance"})
curl -X POST "https://apis.viggle.ai/v1/motions/import" -H "Authorization: Bearer $VIGGLE_API_KEY" -H "Content-Type: application/json" -d '{"template_id":"YOUR_TEMPLATE_ID","name":"Campaign dance"}'
列出、获取、删除和导出动作
req, _ := http.NewRequest("GET", "https://apis.viggle.ai/v1/motions/mot_550e8400-e29b-41d4-a716-446655440000", nil); req.Header.Set("Authorization", "Bearer "+os.Getenv("VIGGLE_API_KEY")); resp, _ := http.DefaultClient.Do(req)
const resp = await fetch(`https://apis.viggle.ai/v1/motions/${motionId}`, {headers:{Authorization:`Bearer ${process.env.VIGGLE_API_KEY}`}});
resp = requests.get(f"https://apis.viggle.ai/v1/motions/{motion_id}", headers={"Authorization": f"Bearer {os.environ['VIGGLE_API_KEY']}"})
curl "https://apis.viggle.ai/v1/motions" -H "Authorization: Bearer $VIGGLE_API_KEY"
curl "https://apis.viggle.ai/v1/motions/mot_550e8400-e29b-41d4-a716-446655440000" -H "Authorization: Bearer $VIGGLE_API_KEY"
curl -X DELETE "https://apis.viggle.ai/v1/motions/mot_550e8400-e29b-41d4-a716-446655440000" -H "Authorization: Bearer $VIGGLE_API_KEY"
curl "https://apis.viggle.ai/v1/motions/mot_550e8400-e29b-41d4-a716-446655440000/export?download_type=mixamo" -H "Authorization: Bearer $VIGGLE_API_KEY"
创建、列出、获取和下载渲染任务
body := &bytes.Buffer{}; w := multipart.NewWriter(body); w.WriteField("character_id", "char_550e8400-e29b-41d4-a716-446655440000"); w.WriteField("motion_id", "mot_550e8400-e29b-41d4-a716-446655440000"); w.Close()
req, _ := http.NewRequest("POST", "https://apis.viggle.ai/v1/renders", body); req.Header.Set("Authorization", "Bearer "+os.Getenv("VIGGLE_API_KEY")); req.Header.Set("Content-Type", w.FormDataContentType()); resp, _ := http.DefaultClient.Do(req)
const form = new FormData(); form.append("character_id", characterId); form.append("motion_id", motionId);
const resp = await fetch("https://apis.viggle.ai/v1/renders", {method:"POST", headers:{Authorization:`Bearer ${process.env.VIGGLE_API_KEY}`}, body:form});
resp = requests.post("https://apis.viggle.ai/v1/renders", headers={"Authorization": f"Bearer {os.environ['VIGGLE_API_KEY']}"}, data={"character_id": character_id, "motion_id": motion_id})
curl -X POST "https://apis.viggle.ai/v1/renders" -H "Authorization: Bearer $VIGGLE_API_KEY" -F "character_id=char_550e8400-e29b-41d4-a716-446655440000" -F "motion_id=mot_550e8400-e29b-41d4-a716-446655440000"
curl "https://apis.viggle.ai/v1/videos?status=ready&limit=20" -H "Authorization: Bearer $VIGGLE_API_KEY"
curl "https://apis.viggle.ai/v1/videos/render_8f50b2c2c2b84ae0" -H "Authorization: Bearer $VIGGLE_API_KEY"
curl -L "https://apis.viggle.ai/v1/renders/render_8f50b2c2c2b84ae0/download" -H "Authorization: Bearer $VIGGLE_API_KEY" -o output.mp4
GET /v1/videos 和 GET /v1/videos/{video_id},见列出视频与获取视频。旧 Render 查询接口已停用,返回 405。
没有取消接口。参数组合与响应字段见渲染任务。
从准备好的草稿创建渲染
curl -X POST "https://apis.viggle.ai/v1/renders/prepare" \
-H "Authorization: Bearer $VIGGLE_API_KEY" \
-H "Content-Type: application/json" \
-d '{"character":{"kind":"asset","asset_id":"char_550e8400-e29b-41d4-a716-446655440000"},"motion":{"kind":"asset","asset_id":"mot_550e8400-e29b-41d4-a716-446655440000"}}'
curl -X POST "https://apis.viggle.ai/v1/renders" \
-H "Authorization: Bearer $VIGGLE_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $(uuidgen)" \
-d '{"draft_id":"draft_abc123"}'
import os, uuid, requests
headers = {"Authorization": f"Bearer {os.environ['VIGGLE_API_KEY']}"}
draft = requests.post(
"https://apis.viggle.ai/v1/renders/prepare",
headers=headers,
json={
"character": {"kind": "asset", "asset_id": "char_550e8400-e29b-41d4-a716-446655440000"},
"motion": {"kind": "asset", "asset_id": "mot_550e8400-e29b-41d4-a716-446655440000"},
},
).json()
render = requests.post(
"https://apis.viggle.ai/v1/renders",
headers={**headers, "Idempotency-Key": str(uuid.uuid4())},
json={"draft_id": draft["draft_id"]},
)
render.raise_for_status()
kind: "upload" 时,先将原始字节 PUT 到 prepare 返回的各个 uploads[].url,再调用 POST /v1/renders。完整流程见准备渲染。
通过 SSE 监听渲染
curl -N "https://apis.viggle.ai/v1/renders/render_8f50b2c2c2b84ae0/events" \
-H "Authorization: Bearer $VIGGLE_API_KEY" \
-H "Accept: text/event-stream"
生成视频 — POST /v1/videos
文本、首帧、首尾帧、参考素材和角色动画生成共用此接口,实际模式由输入字段决定。
curl "https://apis.viggle.ai/v1/videos" \
-H "Authorization: Bearer $VIGGLE_API_KEY" \
-F prompt="a paper airplane gliding through a sunlit office" \
-F quality=low \
-F duration_s=5
curl "https://apis.viggle.ai/v1/videos" \
-H "Authorization: Bearer $VIGGLE_API_KEY" \
-F prompt="camera slowly zooms out" \
-F quality=high \
-F first_frame_image_url=https://example.test/first.png
curl "https://apis.viggle.ai/v1/videos" \
-H "Authorization: Bearer $VIGGLE_API_KEY" \
-F prompt="camera pans across the room" \
-F quality=low \
-F first_frame_image_url=https://example.test/first.png \
-F last_frame_image_url=https://example.test/last.png
curl "https://apis.viggle.ai/v1/videos" \
-H "Authorization: Bearer $VIGGLE_API_KEY" \
-F prompt="keep the same outfit and walk forward" \
-F quality=high \
-F reference_video_url=https://example.test/reference.mp4 \
-F reference_image_url=https://example.test/ref1.png
curl "https://apis.viggle.ai/v1/videos" \
-H "Authorization: Bearer $VIGGLE_API_KEY" \
-F driving_video_url=https://example.test/driving.mp4 \
-F character_image_url=https://example.test/char1.png
import os, requests
resp = requests.post(
"https://apis.viggle.ai/v1/videos",
headers={"Authorization": f"Bearer {os.environ['VIGGLE_API_KEY']}"},
data={"prompt": "camera slowly zooms out", "quality": "high"},
files={"first_frame_image": open("first.png", "rb")},
)
resp.raise_for_status()
video = resp.json()
200 和相同的受理结构 {id, status, progress, created_at}。完整字段与常见错误见文本生成、首帧生成、首尾帧生成、参考素材生成和使用 Viggle-Animate。
各接口请求示例
以下示例展示各接口的 HTTP 方法、路径和请求结构。Go 中client 为 http.Client;JavaScript 中 apiKey 为 API 密钥;Python 中 headers 为 {"Authorization": "Bearer ..."}。
GET /v1/characters
req, _ := http.NewRequest("GET", base+"/characters", nil); req.Header.Set("Authorization", "Bearer "+apiKey); resp, _ := client.Do(req)
const resp = await fetch(`${base}/characters`, {headers:{Authorization:`Bearer ${apiKey}`}});
resp = requests.get(f"{base}/characters", headers=headers)
curl "$BASE/characters" -H "Authorization: Bearer $VIGGLE_API_KEY"
GET /v1/characters/{character_id}
req, _ := http.NewRequest("GET", base+"/characters/"+characterID, nil); req.Header.Set("Authorization", "Bearer "+apiKey); resp, _ := client.Do(req)
const resp = await fetch(`${base}/characters/${characterId}`, {headers:{Authorization:`Bearer ${apiKey}`}});
resp = requests.get(f"{base}/characters/{character_id}", headers=headers)
curl "$BASE/characters/$CHARACTER_ID" -H "Authorization: Bearer $VIGGLE_API_KEY"
DELETE /v1/characters/{character_id}
req, _ := http.NewRequest("DELETE", base+"/characters/"+characterID, nil); req.Header.Set("Authorization", "Bearer "+apiKey); resp, _ := client.Do(req)
const resp = await fetch(`${base}/characters/${characterId}`, {method:"DELETE", headers:{Authorization:`Bearer ${apiKey}`}});
resp = requests.delete(f"{base}/characters/{character_id}", headers=headers)
curl -X DELETE "$BASE/characters/$CHARACTER_ID" -H "Authorization: Bearer $VIGGLE_API_KEY"
GET /v1/characters/{character_id}/export
req, _ := http.NewRequest("GET", base+"/characters/"+characterID+"/export?download_type=vsplat", nil); req.Header.Set("Authorization", "Bearer "+apiKey); resp, _ := client.Do(req)
const resp = await fetch(`${base}/characters/${characterId}/export?download_type=vsplat`, {headers:{Authorization:`Bearer ${apiKey}`}});
resp = requests.get(f"{base}/characters/{character_id}/export", params={"download_type": "vsplat"}, headers=headers)
curl "$BASE/characters/$CHARACTER_ID/export?download_type=vsplat" -H "Authorization: Bearer $VIGGLE_API_KEY"
GET /v1/motions
req, _ := http.NewRequest("GET", base+"/motions", nil); req.Header.Set("Authorization", "Bearer "+apiKey); resp, _ := client.Do(req)
const resp = await fetch(`${base}/motions`, {headers:{Authorization:`Bearer ${apiKey}`}});
resp = requests.get(f"{base}/motions", headers=headers)
curl "$BASE/motions" -H "Authorization: Bearer $VIGGLE_API_KEY"
GET /v1/motions/{motion_id}
req, _ := http.NewRequest("GET", base+"/motions/"+motionID, nil); req.Header.Set("Authorization", "Bearer "+apiKey); resp, _ := client.Do(req)
const resp = await fetch(`${base}/motions/${motionId}`, {headers:{Authorization:`Bearer ${apiKey}`}});
resp = requests.get(f"{base}/motions/{motion_id}", headers=headers)
curl "$BASE/motions/$MOTION_ID" -H "Authorization: Bearer $VIGGLE_API_KEY"
DELETE /v1/motions/{motion_id}
req, _ := http.NewRequest("DELETE", base+"/motions/"+motionID, nil); req.Header.Set("Authorization", "Bearer "+apiKey); resp, _ := client.Do(req)
const resp = await fetch(`${base}/motions/${motionId}`, {method:"DELETE", headers:{Authorization:`Bearer ${apiKey}`}});
resp = requests.delete(f"{base}/motions/{motion_id}", headers=headers)
curl -X DELETE "$BASE/motions/$MOTION_ID" -H "Authorization: Bearer $VIGGLE_API_KEY"
GET /v1/motions/{motion_id}/export
req, _ := http.NewRequest("GET", base+"/motions/"+motionID+"/export?download_type=mixamo", nil); req.Header.Set("Authorization", "Bearer "+apiKey); resp, _ := client.Do(req)
const resp = await fetch(`${base}/motions/${motionId}/export?download_type=mixamo`, {headers:{Authorization:`Bearer ${apiKey}`}});
resp = requests.get(f"{base}/motions/{motion_id}/export", params={"download_type": "mixamo"}, headers=headers)
curl "$BASE/motions/$MOTION_ID/export?download_type=mixamo" -H "Authorization: Bearer $VIGGLE_API_KEY"
GET /v1/videos
替代已停用并返回 405 Method Not Allowed 的 GET /v1/renders,统一列出渲染及视频生成结果。
req, _ := http.NewRequest("GET", base+"/videos?status=ready&limit=20", nil); req.Header.Set("Authorization", "Bearer "+apiKey); resp, _ := client.Do(req)
const resp = await fetch(`${base}/videos?status=ready&limit=20`, {headers:{Authorization:`Bearer ${apiKey}`}});
resp = requests.get(f"{base}/videos", params={"status": "ready", "limit": 20}, headers=headers)
curl "$BASE/videos?status=ready&limit=20" -H "Authorization: Bearer $VIGGLE_API_KEY"
GET /v1/videos/{video_id}
替代已停用并返回 405 Method Not Allowed 的 GET /v1/renders/{render_id}。接受 render_、vid_ 和 anim_ 前缀 ID。
req, _ := http.NewRequest("GET", base+"/videos/"+videoID, nil); req.Header.Set("Authorization", "Bearer "+apiKey); resp, _ := client.Do(req)
const resp = await fetch(`${base}/videos/${videoId}`, {headers:{Authorization:`Bearer ${apiKey}`}});
resp = requests.get(f"{base}/videos/{video_id}", headers=headers)
curl "$BASE/videos/$VIDEO_ID" -H "Authorization: Bearer $VIGGLE_API_KEY"
GET /v1/renders/{render_id}/events
req, _ := http.NewRequest("GET", base+"/renders/"+renderID+"/events", nil); req.Header.Set("Authorization", "Bearer "+apiKey); req.Header.Set("Accept", "text/event-stream"); resp, _ := client.Do(req)
curl -N "$BASE/renders/$RENDER_ID/events" -H "Authorization: Bearer $VIGGLE_API_KEY" -H "Accept: text/event-stream"
GET /v1/renders/{render_id}/download
req, _ := http.NewRequest("GET", base+"/renders/"+renderID+"/download", nil); req.Header.Set("Authorization", "Bearer "+apiKey); resp, _ := client.Do(req)
const resp = await fetch(`${base}/renders/${renderId}/download`, {headers:{Authorization:`Bearer ${apiKey}`}});
resp = requests.get(f"{base}/renders/{render_id}/download", headers=headers, allow_redirects=True)
curl -L "$BASE/renders/$RENDER_ID/download" -H "Authorization: Bearer $VIGGLE_API_KEY" -o output.mp4

