Developers
Mascots as an API.
Create, rebuild, animate and embed characters from your code, your terminal or your agent.
npx lumorig loginhttps://lumorig.com/api/mcp$ lumorig create "a vector control point that came alive"drawing body, pupils, eyes, brows…reviewing a draft✔ Designing your mascot ($0.28)Pip msc_4hq8z readypalette cobalt_hi #6682FF cobalt #3A5BFF cobalt_mid #3452F2$ lumorig play msc_4hq8z wave
Four surfaces, one engine
The studio, the API, the SDK, MCP and the CLI all call the same service layer.
Quickstart
Create, wait, export, embed.
- 1
Create
From an idea, an upload or an image URL. Returns at once with a job.
curlcurl -X POST https://lumorig.com/api/v1/mascots -H "Authorization: Bearer $LUMORIG_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "prompt": "a sleepy moth who guards the docs" }' # 202 → { "mascot": { "id": "msc_…" }, "job": { "id": "job_…" } } - 2
Wait
Long-poll the job, stream its events over SSE, or get a webhook.
curlcurl "https://lumorig.com/api/v1/jobs/job_…?wait=30" -H "Authorization: Bearer $LUMORIG_API_KEY" # or stream progress as it draws curl -N "https://lumorig.com/api/v1/jobs/job_…/events" -H "Authorization: Bearer $LUMORIG_API_KEY" - 3
Export
Any format, any size. Presets and exports never cost credits.
curlcurl -X POST https://lumorig.com/api/v1/mascots/msc_…/exports -H "Authorization: Bearer $LUMORIG_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "format": "lottie", "animation": "wave" }' - 4
Embed
Or skip files: one line of HTML, live and interactive.
curlcurl "https://lumorig.com/api/v1/mascots/msc_…/bundle" # what <lumorig-player> loads
Uploads, custom motion, canvases and webhooks are in the full quickstart and the API reference.
Built for agents
14 tools your agent already understands.
claude mcp add --transport http lumorig \
https://lumorig.com/api/mcp \
--header "Authorization: Bearer $LUMORIG_API_KEY"{
"mcpServers": {
"lumorig": {
"command": "npx",
"args": ["-y", "@lumorig/mcp"],
"env": { "LUMORIG_API_KEY": "lr_sk_…" }
}
}
}Plus the MCP guide, llms.txt, OpenAPI and a Claude Code skill, so agents can read the docs the way they like them.
create_mascotNew character from an idea, or rebuild an imagelist_mascotsEverything in the workspaceget_mascotParts, palette, motions and a preview imageedit_mascotChange it in plain words, or branch a look variantrecolor_mascotSwap palette tokens instantlyanimate_mascotA preset (free), a described motion or a reference videosuggest_animationsSignature-motion ideas for your productexport_mascotLottie, SVG, MP4, WebM, GIF, stickers…get_embed_codeA ready <lumorig-player> or Lottie snippetcreate_canvasChatbot, AI-agent or onboarding behaviourcreate_sceneThe mascot in an illustrated vector sceneanalyze_websiteThree mascot concepts from a brand's sitewait_for_jobBlock until a long job finisheslist_jobsRecent jobs, status and cost
Terminal companion
A mascot that watches your agent work.
Run lumorig companion in a side terminal and add the hooks. It shows working during tool calls, waiting when Claude Code needs you, and done when it stops.
{
"hooks": {
"UserPromptSubmit": [{ "hooks": [{ "type": "command", "command": "lumorig state working" }] }],
"PreToolUse": [{ "matcher": "*", "hooks": [{ "type": "command", "command": "lumorig state working" }] }],
"Notification": [{ "hooks": [{ "type": "command", "command": "lumorig state waiting" }] }],
"Stop": [{ "hooks": [{ "type": "command", "command": "lumorig state done" }] }]
}
}lumorig companion
idle$ claude "fix the flaky auth test"
Runtime
<lumorig-player>: ~8 KB gzipped, one line of HTML.
<lumorig-player
src="https://lumorig.com/api/v1/mascots/pip/bundle"
animation="wave"
trigger="auto"
follow-cursor
></lumorig-player>| attribute | type | does |
|---|---|---|
| src | URL | Mascot bundle (spec + motions + canvases) |
| animation | string | Preset or motion name to play |
| trigger | auto · hover · click · none | When it plays |
| speed | number | Playback rate, 1 = normal |
| loop | boolean | Loop the animation |
| palette | JSON | Recolour by token, e.g. {"fur":"#3A5BFF"} |
| follow-cursor | boolean | Eyes and head track the pointer |
| canvas | string | Run a state machine from the bundle |
| no-shadow | boolean | Hide the soft floor shadow |
play(name?)Play a motion nowpause() · seek(t)Control the timelinesetInput(name, value)Drive a canvas inputfire(name)Fire a canvas triggerready · ended · statechange · errorEvents you can listen to
import { MascotPlayer } from "@lumorig/player/react";
export function Helper() {
return (
<MascotPlayer
src="https://lumorig.com/api/v1/mascots/pip/bundle"
animation="idle"
trigger="hover"
followCursor
/>
);
}Jobs & webhooks
Everything slow is a job. Every job tells you what it cost.
- queued
- running
- succeeded
- …or failed · canceled. Events stream over SSE while it runs.
- Long-poll with
?wait=30, or stream/jobs/:id/events. - Webhooks for
job.succeeded,job.failed,job.canceled, HMAC-signed and retried. - Signed share links for private mascots, with an expiry you choose.
- Cost ceilings: every model job stops at a ceiling tied to its price; pass
max_cost_usdon create, edit, variant, motion and scene jobs to set a lower one.
POST https://your.app/hooks/lumorig
lumorig-signature: t=1790000000,v1=5f2c…
{
"type": "job.succeeded",
"created_at": "2026-09-25T10:04:12Z",
"data": {
"id": "job_…", "type": "export", "status": "succeeded",
"cost_usd": 0, "result": { "file": { "url": "/api/v1/files/file_…" } }
}
}curl -X POST https://lumorig.com/api/v1/webhooks \
-H "Authorization: Bearer $LUMORIG_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "url": "https://your.app/hooks/lumorig", "events": ["job.succeeded", "job.failed"] }'Reliability and limits
Sanitised SVG
Every drawing passes a restricted-subset sanitiser before it's stored or served. No scripts, no external references.
Versioned formats
Specs, clips and canvases carry a version field (specVersion, clipVersion, canvasVersion), and every save is validated against the schema.
No surprise bills
Credits are held up front and refunded if a job fails. Every model job has a hard cost ceiling, and max_cost_usd lowers it. Presets and exports are always free.