curl --request GET \
--url https://apis.viggle.ai/v1/motions/{motion_id} \
--header 'Authorization: Bearer <token>'import requests
url = "https://apis.viggle.ai/v1/motions/{motion_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/motions/{motion_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/motions/{motion_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/motions/{motion_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/motions/{motion_id}")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("https://apis.viggle.ai/v1/motions/{motion_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",
"name": "<string>",
"progress": 50,
"capabilities": [
"<string>"
],
"created_at": "<string>",
"completed_at": "<string>",
"error": {
"code": "<string>",
"message": "<string>",
"request_id": "<string>"
},
"type": "render",
"vsplat": {
"status": "queued",
"error": {
"code": "<string>",
"message": "<string>",
"request_id": "<string>"
}
},
"glb": {
"status": "queued",
"skeletons": [
"mixamo"
],
"error": {
"code": "<string>",
"message": "<string>",
"request_id": "<string>"
}
}
}{
"error": {
"code": "authentication_required",
"message": "<string>",
"request_id": "<string>"
}
}{
"error": {
"code": "authentication_required",
"message": "<string>",
"request_id": "<string>"
}
}{
"error": {
"code": "authentication_required",
"message": "<string>",
"request_id": "<string>"
}
}{
"error": {
"code": "authentication_required",
"message": "<string>",
"request_id": "<string>"
}
}{
"error": {
"code": "authentication_required",
"message": "<string>",
"request_id": "<string>"
}
}Get Motion
Retrieve the current state of one Motion.
curl --request GET \
--url https://apis.viggle.ai/v1/motions/{motion_id} \
--header 'Authorization: Bearer <token>'import requests
url = "https://apis.viggle.ai/v1/motions/{motion_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/motions/{motion_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/motions/{motion_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/motions/{motion_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/motions/{motion_id}")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("https://apis.viggle.ai/v1/motions/{motion_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",
"name": "<string>",
"progress": 50,
"capabilities": [
"<string>"
],
"created_at": "<string>",
"completed_at": "<string>",
"error": {
"code": "<string>",
"message": "<string>",
"request_id": "<string>"
},
"type": "render",
"vsplat": {
"status": "queued",
"error": {
"code": "<string>",
"message": "<string>",
"request_id": "<string>"
}
},
"glb": {
"status": "queued",
"skeletons": [
"mixamo"
],
"error": {
"code": "<string>",
"message": "<string>",
"request_id": "<string>"
}
}
}{
"error": {
"code": "authentication_required",
"message": "<string>",
"request_id": "<string>"
}
}{
"error": {
"code": "authentication_required",
"message": "<string>",
"request_id": "<string>"
}
}{
"error": {
"code": "authentication_required",
"message": "<string>",
"request_id": "<string>"
}
}{
"error": {
"code": "authentication_required",
"message": "<string>",
"request_id": "<string>"
}
}{
"error": {
"code": "authentication_required",
"message": "<string>",
"request_id": "<string>"
}
}GET /v1/motions/{motion_id} retrieves a Motion. Poll while its status is queued or processing.
Request parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
motion_id | string | Yes | Complete Motion ID returned by Create, Import, or List Motions, normally beginning with mot_. Poll with the same value until every requested output is ready or failed. |
Response parameters
Returns200 OK with the Motion fields documented in Create Motion (from Video) and Create Motion (from Text), including type and glb. error is always null here — read status to detect failure (on a glb/all Motion, check glb.error for extraction-specific failure detail).
{"id":"mot_456def","status":"ready","name":"Dance loop","progress":100,"capabilities":["video_render"],"created_at":"2026-07-21T10:00:00+00:00","completed_at":"2026-07-21T10:00:20+00:00","error":null,"type":"render","vsplat":null,"glb":null}
Examples
id := "mot_456def"; req, _ := http.NewRequest("GET", "https://apis.viggle.ai/v1/motions/"+id, 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()
const response = await fetch("https://apis.viggle.ai/v1/motions/mot_456def", {headers:{Authorization:`Bearer ${process.env.VIGGLE_API_KEY}`}}); const motion = await response.json();
import os, requests
response=requests.get("https://apis.viggle.ai/v1/motions/mot_456def",headers={"Authorization":f"Bearer {os.environ['VIGGLE_API_KEY']}"}); response.raise_for_status(); motion=response.json()
curl "https://apis.viggle.ai/v1/motions/mot_456def" -H "Authorization: Bearer $VIGGLE_API_KEY"
Next step
Once aglb/all Motion’s glb.status is ready, use Export 3D Motion (for 3D/game engines) to get its download URL.Authorizations
Server-side SDK clients use a project API key. Remote MCP clients use an OAuth access token. Never expose a project API key in browser code.
Headers
Optional caller-supplied correlation ID, up to 128 characters. The service returns the effective value in the response header for tracing and support.
1 - 128Optional source-channel label, up to 128 characters, used to attribute traffic to an SDK, integration, product surface, or internal workflow.
1 - 128Path Parameters
Public Motion ID returned by motion creation or listing. It normally begins with mot_ and must identify a Motion owned by the caller.
1Response
Current motion state.
A character or motion asset. Both resources share one wire shape.
progress is null in list responses. error is always null, including
on a failed asset: read status to detect failure.
type reflects what was requested at creation. For characters it is
render, vsplat, or all; for motions it is render, glb,
or all. Assets created before type existed report render.
vsplat and glb carry that extraction's own status — never
download URLs, which come from GET /v1/characters/{character_id}/export
or GET /v1/motions/{motion_id}/export instead — and are null unless
type requested that extraction. On an all asset, the top-level
status only reaches ready once both the 2D render and the 3D
extraction have; if either fails, the top-level status is failed
while the sub-object's own status still shows which one it was.
Public asset identifier. Character IDs normally begin with char_; Motion IDs normally begin with mot_.
1Overall lifecycle of the asset. Use an asset for rendering or export only after the required capability becomes ready.
queued, processing, ready, failed, cancelled Display name supplied at creation or derived during import; it may be empty when a workflow does not accept a name.
Best-effort processing percentage from 0 through 100 on detail responses; null in list responses or when unavailable.
0 <= x <= 100What the asset can be used for. video_render appears once the
asset is ready.
ISO 8601 timestamp with a UTC offset, for example 2026-07-31T09:15:22+00:00.
ISO 8601 timestamp with a UTC offset when all requested processing reached a terminal state; null while work is active.
Reserved top-level failure detail. It is currently always null; detect failure from status and inspect extraction sub-objects when applicable.
Show child attributes
Show child attributes
Work requested when the asset was created. render produces the 2D render-ready asset, vsplat/glb requests 3D output, and all requests both supported outputs.
render, vsplat, glb, all Character vsplat extraction status. Null for motions, and for
characters whose type is render. The request parameters
(model_precision, etc.) submitted at creation are not echoed
back here — this is status only.
Show child attributes
Show child attributes
Motion 3D animation extraction/generation status. Null for
characters, and for motions whose type is render.
Show child attributes
Show child attributes

