Spec · v1.0
The Avatar Package
One portable format for a living avatar: a base face, a set of FACS expression frames, and a manifest that ties them together. No runtime AI.
What it is
avatar-package/1.0 is a small, stable descriptor plus its image assets.
It comes in two shapes, same schema:
- Hosted:
https://studio.rosto.ai/pub/TOKEN/manifest.json. Paths are absolute CDN URLs; the public token is a revocable capability. This is what an embed loads. - Standalone: the downloadable bundle. Paths are relative; the whole avatar is self-contained and self-hostable, with zero dependency on Rosto.
The manifest
A single JSON object. The only difference between the two shapes is whether
base/frames hold absolute URLs or relative paths.
| field | type | meaning |
|---|---|---|
spec | string | always avatar-package/1.0 |
name | string? | display name (may be null) |
style_id | string | the visual style the face was rendered in |
content_hash | string | sha256 of the base image; a stable identity for this face |
base | string | URL or relative path to the base face image |
frames | object | { frame_id: url_or_path }, one entry per Action Unit |
provenance | object | generator, model, consent_attested, license (hosted or self-hosted) |
approved | bool | hosted only; false = preview, not yet publishable |
allowed_domains | array | hosted only; empty = loads anywhere, else an allow-list |
Standalone bundle:
{
"spec": "avatar-package/1.0",
"name": "Ava",
"style_id": "studio-clean",
"content_hash": "9f2c…",
"base": "base.png",
"frames": { "smile_warm": "frames/smile_warm.png", "brows_up": "frames/brows_up.png" },
"provenance": { "generator": "avatar-studio@…", "consent_attested": true, "license": "self-hosted" }
}
Hosted (embedded) manifest:
{
"spec": "avatar-package/1.0",
"base": "https://studio.rosto.ai/pub/TOKEN/9f2c….png",
"frames": { "smile_warm": "https://studio.rosto.ai/pub/TOKEN/1a4e….png", "brows_up": "…" }
}
Frames are Action Units
Each frames entry is one identity-preserving edit of the base along a single
FACS channel: a raised brow, a warm smile, a viseme mouth shape, a gaze direction.
The rig composes emotions and speech from these at runtime; blinks, breath, gaze
saccades and lip-sync are procedural, so no extra assets are needed. To animate without
our rig, cross-fade base with the relevant frames; the ids name the channels.
Driving it — the rig API
Mount the manifest, get a controller back. Framework-free; a plain browser global.
<div id="avatar"></div>
<script src="./avatar-rig.js"></script> <!-- or https://studio.rosto.ai/rig/avatar-rig.js -->
<script>
fetch('./manifest.json').then(r => r.json()).then(m => {
const rig = AvatarRig.mount(document.getElementById('avatar'), m, { size: 320 });
rig.setState('idle');
});
</script>
rig.setState("listening"); // idle · listening · thinking · speaking · acknowledging\nrig.setMood("warm"); // a persistent baseline affect\nrig.express("genuine-joy"); // a composed emotion (manifest.frames defines the set)\nrig.react("delight"); // a brief impulse that decays back to mood\nrig.speak("Hello there!"); // text-driven viseme lip-sync\nrig.command({ state:"speaking", emotion:"curious", say:"Tell me more?" });
Self-hosting the bundle
The standalone bundle runs anywhere. This is the "you own it" guarantee.
rosto-<name>/
├─ manifest.json avatar-package/1.0 descriptor (relative paths)
├─ base.png the stylized base face
├─ frames/ the FACS expression frames (Action Units)
├─ avatar-rig.js the runtime — a browser global, ~30 KB, no dependencies
├─ index.html a runnable demo (double-click, works offline)
├─ README.md human quickstart + this protocol
└─ AGENTS.md instructions your AI agent reads to wire it in- Locally — open
index.html(the manifest is inlined, sofile://works). - Any static host — upload the folder (S3, GitHub Pages, your server) and open it.
- In your app — copy the folder into your served assets and mount the rig (above).
Let your AI agent integrate it
The bundle ships an AGENTS.md. Drop the folder into your project and tell your
coding agent (Claude Code, Cursor, Windsurf, Copilot) "integrate this avatar." It reads
AGENTS.md and writes the wiring for your framework.
To create or manage avatars programmatically, point any MCP-capable agent at the Rosto MCP server:
{ "mcpServers": { "rosto": { "url": "https://mcp.rosto.ai/mcp" } } }\n// tools: start_free · create_avatar · build_frames · approve · get_embed_guide
Every image is invisibly watermarked to its owner; generated media is provenance-stamped; consent is attested at creation.