All animation goes through one endpoint, POST /mascots/{id}/animations, with four body shapes: a preset, a prompt, a reference_upload_id, or a hand-authored clip. Whatever you create is saved on the mascot under its name and travels in the player bundle.
Presets#
31 motions, fitted to each rig without a model call. They answer at once with 201, cost nothing, and work on every character, whatever its shape. Presets are always usable by id (in exports, embeds, canvases) even if you never save them; saving one lets you give it your own intensity, duration and name.
| preset | Default length | Motion |
|---|---|---|
idle | 4s | Breathing, blinking, a little life |
wave | 2s | Friendly hello |
nod | 1.2s | Yes! |
shake | 1.2s | Nope |
bounce | 1s | Springy squash and stretch |
celebrate | 1.6s | Arms up, big joy |
jump | 1.4s | A big hop |
talk | 2s | Chatty mouth for assistants |
sad | 3s | Droopy and blue |
surprised | 1.6s | Whoa! |
dance | 2s | Groove on the beat |
think | 3s | Hmm… pondering |
working | 1.2s | Busy, focused hustle |
listen | 2.4s | Attentive, leaning in |
sleep | 4s | Snoozing |
fly | 1.6s | Wings flap, feet off the ground |
point | 2.8s | Points to the side, looking where it points |
shrug | 2s | Arms out, not sure |
float | 4s | Hovers off the ground, calm |
peek | 3.8s | Peeks up from the bottom edge, looks around, ducks |
laugh | 1.8s | Eyes shut, shaking with laughter |
type | 2.4s | Types on a laptop |
ride | 3.2s | Rolls along on what it stands on |
notes | 6s | Writes on a notepad line by line, looks up, writes on, turns the page |
read | 5s | Reads along an open book |
sign | 2.4s | Shows a sign with both hands |
search | 3.2s | Looks through a magnifying glass |
phone | 3s | Checks its phone |
sip | 3.2s | Lifts a mug and takes a sip |
announce | 2.6s | Calls out through a megaphone |
walk | 2.4s | Walks in place on all its legs |
curl -X POST https://lumorig.com/api/v1/mascots/msc_…/animations -H "Authorization: Bearer $LUMORIG_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "preset": "celebrate", "intensity": 1.4, "duration": 2, "name": "big-win" }'
# 201 → { "animation": { "id": "anm_…", "name": "big-win", "source": "preset", "preset": "celebrate", "duration": 2, "loop": true, … } }| Name | Type | Description |
|---|---|---|
presetrequired | string | One of the ids above. GET /presets lists them without a key. |
intensity | number | 0.25–2. About 0.5 is subtle, 1 normal, 1.5 big. |
arm | string | Wave only: auto, left, right or both, from the viewer's side. An arm that is missing, holds a prop or whose joint is graded down falls back to auto (the clip's notes say why). |
duration | number | Seconds, 0.3–20. Defaults to the preset's length. |
name | string | Max 60 characters. Defaults to the preset's label (e.g. Celebrate). |
Motions from words#
Describe anything else and the Animator agent choreographs it for this rig: keyframes with anticipation and overshoot, expression changes, and spring follow-through on dangling parts. It costs 20 credits, runs as a job, and usually finishes in under a minute.
A rig moves the parts it has. A motion that needs a prop, a seat or another angle (rows on a rowing machine, rides a bike, sits at a desk) is refused before any credits are spent, with 409 needs_video, and offered as a video clip instead: POST /mascots/:id/video-clips with the same prompt draws the character in that pose, animates it, and returns the clip on a "(video)" companion character in your library (70 credits; 60 when the drawing already shows the pose). Pass rig_only: true to get the rig's own attempt anyway.
curl -X POST https://lumorig.com/api/v1/mascots/msc_…/animations -H "Authorization: Bearer $LUMORIG_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "prompt": "hops twice, then does a tiny bow", "duration": 2.5, "name": "bow" }'
# 202 → { "job": { "id": "job_…", "type": "animate", "status": "queued", … } }| Name | Type | Description |
|---|---|---|
promptrequired | string | The motion, 3–1,000 characters. Describe beats and timing, not camera moves. |
duration | number | Seconds, 0.3–20. Omit it to let the Animator choose. |
name | string | Max 60 characters. Defaults to the name the Animator gives the clip. |
max_credits | number | The most credits this job may charge: it stops and is refunded if it would need more. Without it, work past the price is charged once the job delivers. |
The finished job's result has animation_id, the animation itself and a one-line summary. While it works, the event stream carries draft_clip events with each draft clip.
Motions from a reference video#
Film someone (or something) doing the motion, upload the clip, and the Animator watches frames sampled from it and performs the same motion on your rig. Same price as a motion from words: 20 credits.
# 1. upload the reference (MP4, MOV or WebM, up to 15 MB)
curl -X POST https://lumorig.com/api/v1/uploads -H "Authorization: Bearer $LUMORIG_API_KEY" -F "file=@./wave.mp4"
# 201 → { "id": "file_…", "kind": "video", "mime": "video/mp4", … }
# 2. perform it
curl -X POST https://lumorig.com/api/v1/mascots/msc_…/animations -H "Authorization: Bearer $LUMORIG_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "reference_upload_id": "file_…", "prompt": "only the right arm; keep the body still" }'| Name | Type | Description |
|---|---|---|
reference_upload_idrequired | string | An uploaded video (kind: "video"). An image upload returns 400. |
prompt | string | Optional guidance, max 1,000 characters. |
duration | number | Seconds, 0.3–12. |
name | string | Max 60 characters. |
max_credits | number | The most credits this job may charge: it stops and is refunded if it would need more. Without it, work past the price is charged once the job delivers. |
Batches and suggestions#
Several motions at once#
POST/mascots/{id}/animations/batch takes up to 8 prompts (and an optional shared duration) and starts one job each. The whole batch is checked against your balance up front (20 credits per prompt), so it either starts completely or returns 402.
curl -X POST https://lumorig.com/api/v1/mascots/msc_…/animations/batch -H "Authorization: Bearer $LUMORIG_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "prompts": ["peeks out from the left", "typing furiously", "shrugs, then smiles"] }'
# 202 → { "object": "list", "data": [{ "id": "job_…", "type": "animate", … }, …] }Signature-motion ideas#
POST/mascots/{id}/suggestions proposes motions that fit this character and where it will appear. Pass an optional use_case (max 500 characters). Unlike other jobs, this request waits (up to about 90 seconds) and returns the finished job, whose result.suggestions is a list of { name, prompt, moment }. It costs 5 credits. Feed any prompt back into a motion from words.
curl -X POST https://lumorig.com/api/v1/mascots/msc_…/suggestions -H "Authorization: Bearer $LUMORIG_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "use_case": "onboarding guide in a budgeting app" }'Managing animations#
| Endpoint | Does |
|---|---|
GET/mascots/{id}/animations | List saved animations (without their clips). |
GET/mascots/{id}/animations/{animationId} | One animation, including its clip. |
DELETE/mascots/{id}/animations/{animationId} | Remove it from the mascot and future bundles. |
Anywhere the API asks for an animation you can pass an animation id, a saved name (the newest wins if two share a name), or a preset id. Names are what the player uses: <lumorig-player animation="bow">.
Hand-authored clips#
Send { "clip": { … }, "name": "…" } to save an AnimationClip you wrote or edited yourself. It is validated against the rig (known parts and states, rotation within joint limits, looping tracks that start and end on the same value) and saved with source: "custom", free and instantly. Problems come back as a 400 with a list in error.details.