{"openapi":"3.1.0","info":{"title":"UniMate for Agents: text-to-animation API (ZeroGPU)","description":"Generate a 60-frame (2 s, 30 fps) motion for a rigged skeleton from a text prompt with UniMate (SIGGRAPH Asia 2026), then download it as an animated GLB, raw motion features (.npy), per-frame joint positions (JSON) and a skeleton preview. Synchronous: POST /api/animate returns when the files are ready. The upstream editing modes are exposed too: POST /api/inbetween (regenerate frames between kept frames of an earlier result), POST /api/edit (regenerate some joints, keep the others) and POST /api/expand (chain several prompts into one long motion, 60 + 50 frames per extra prompt). Agent guide: /llms.txt. MCP: /gradio_api/mcp/.","version":"1.1"},"paths":{"/api":{"get":{"tags":["service"],"summary":"Service description: parameters, limits, workflow, provenance","operationId":"api_info_api_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Api Info Api Get"}}}}}}},"/api/health":{"get":{"tags":["service"],"summary":"Health","operationId":"health_api_health_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Health Api Health Get"}}}}}}},"/api/gpu_check":{"get":{"tags":["service"],"summary":"Run a 10 s ZeroGPU probe (billed to the caller) and report the GPU","operationId":"api_gpu_check_api_gpu_check_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Api Gpu Check Api Gpu Check Get"}}}}}}},"/api/examples":{"get":{"tags":["service"],"summary":"Real examples generated by this Space, with file URLs and how to reproduce each","operationId":"api_examples_api_examples_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Api Examples Api Examples Get"}}}}}}},"/api/identity":{"get":{"tags":["service"],"summary":"Who pays the GPU time of calls made with these headers","operationId":"api_identity_api_identity_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Api Identity Api Identity Get"}}}}}}},"/api/assets":{"get":{"tags":["assets"],"summary":"The skeletons that can be animated","operationId":"api_assets_api_assets_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Api Assets Api Assets Get"}}}}}},"post":{"tags":["assets"],"summary":"Upload your own rigged asset (a rig_preprocess output directory, zipped)","description":"Preprocess a rigged GLB/glTF/FBX with the UniMate repository (`python -m data_process.rig_preprocess run --input rig.glb --output_dir out`), then send `out/` as a zip: raw request body (curl --data-binary @out.zip) or multipart with a `file` field. The id is derived from the file bytes, so the same upload is free to repeat. Rigs with more than 71 joints are refused.","operationId":"api_upload_api_assets_post","parameters":[{"name":"filename","in":"query","required":false,"schema":{"type":"string","description":"original file name","default":"asset.zip","title":"Filename"},"description":"original file name"}],"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Api Upload Api Assets Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/assets/{asset_id}":{"get":{"tags":["assets"],"summary":"One skeleton: joints, labels, hierarchy","operationId":"api_asset_api_assets__asset_id__get","parameters":[{"name":"asset_id","in":"path","required":true,"schema":{"type":"string","title":"Asset Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Api Asset Api Assets  Asset Id  Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/assets/{asset_id}/rest.glb":{"get":{"tags":["assets"],"summary":"The canonical rest-pose GLB of a skeleton","operationId":"api_asset_glb_api_assets__asset_id__rest_glb_get","parameters":[{"name":"asset_id","in":"path","required":true,"schema":{"type":"string","title":"Asset Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/animate":{"post":{"tags":["animate"],"summary":"Generate motion for a skeleton from a prompt (synchronous, a few seconds)","description":"Body: {\"asset\": \"unitree_go2\", \"prompt\": \"An object trots forward.\", \"num_samples\": 1, \"cfg_scale\": 3.0, \"seed\": 7, \"preview\": true}. Returns the result with a URL per output file. GPU time is billed to the caller's ZeroGPU quota (send Authorization: Bearer <HF token>).","operationId":"api_animate_api_animate_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Api Animate Api Animate Post"}}}}}}},"/api/inbetween":{"post":{"tags":["animate"],"summary":"In-betweening: keep some frames of an earlier result, regenerate the rest from a prompt","description":"Body: {\"reference_job_id\": \"a_...\", \"reference_sample\": 0, \"reference_start\": 0, \"keep_frames\": \"0,-1\", \"prompt\": \"An object jumps in place.\", \"num_samples\": 1, \"cfg_scale\": 3.0, \"seed\": 7, \"preview\": true}. The kept frames (indices into the 60-frame window; negatives from the end; list or comma-separated string) come out identical to the reference, every other frame is regenerated under the prompt (upstream --inbetween --keep_frames). The result records the resolved keep_frames and the reference.","operationId":"api_inbetween_api_inbetween_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Api Inbetween Api Inbetween Post"}}}}}}},"/api/edit":{"post":{"tags":["animate"],"summary":"Joint editing: keep some joints of an earlier result, regenerate the others from a prompt","description":"Body: {\"reference_job_id\": \"a_...\", \"reference_sample\": 0, \"reference_start\": 0, \"keep_joints\": \"Left Thigh, Right Thigh, Left Shin, Right Shin\", \"prompt\": \"An object flaps its wings.\", \"num_samples\": 1, \"cfg_scale\": 3.0, \"seed\": 7, \"preview\": true}. keep_joints are joint names or anatomical labels of the asset (GET /api/assets/{id}), case-insensitive, list or comma-separated; a label selects every joint carrying it. Kept joints come out identical to the reference over all 60 frames, the other joints are regenerated under the prompt (upstream --motion_edit --keep_joints). The result lists the kept and edited joints.","operationId":"api_edit_api_edit_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Api Edit Api Edit Post"}}}}}}},"/api/expand":{"post":{"tags":["animate"],"summary":"Motion expansion: chain several prompts into one long motion","description":"Body: {\"asset\": \"unitree_go2\", \"prompts\": [\"An object trots forward.\", \"An object turns around.\", \"An object sits down.\"], \"overlap\": 10, \"num_samples\": 1, \"cfg_scale\": 3.0, \"seed\": 7, \"preview\": true}. One 60-frame segment per prompt (2-6); each segment after the first is generated with its first `overlap` frames pinned to the previous segment's last `overlap` frames, so the motion is continuous: 60 + (60 - overlap) x (prompts - 1) frames in one GLB / .npy / JSON (upstream --motion_expand --expand_overlap). num_samples x prompts is limited to 8 per call (about 7 s of GPU time each).","operationId":"api_expand_api_expand_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Api Expand Api Expand Post"}}}}}}},"/api/jobs/{job_id}":{"get":{"tags":["animate"],"summary":"A finished result (kept 24 h)","operationId":"api_job_api_jobs__job_id__get","parameters":[{"name":"job_id","in":"path","required":true,"schema":{"type":"string","title":"Job Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Api Job Api Jobs  Job Id  Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/jobs/{job_id}/files/{name}":{"get":{"tags":["animate"],"summary":"Download an output file","operationId":"api_job_file_api_jobs__job_id__files__name__get","parameters":[{"name":"job_id","in":"path","required":true,"schema":{"type":"string","title":"Job Id"}},{"name":"name","in":"path","required":true,"schema":{"type":"string","title":"Name"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}}},"components":{"schemas":{"HTTPValidationError":{"properties":{"detail":{"items":{"$ref":"#/components/schemas/ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"},"ValidationError":{"properties":{"loc":{"items":{"anyOf":[{"type":"string"},{"type":"integer"}]},"type":"array","title":"Location"},"msg":{"type":"string","title":"Message"},"type":{"type":"string","title":"Error Type"},"input":{"title":"Input"},"ctx":{"type":"object","title":"Context"}},"type":"object","required":["loc","msg","type"],"title":"ValidationError"}}},"servers":[{"url":"https://townbox-unimate-for-agents.hf.space"}]}