Casola Avatar Interaction API

Start a live avatar session, choose which avatar answers, and shape how it behaves — from your own backend, with your own API key.

These docs cover the interaction surface: selecting an avatar, minting a session, connecting a browser to it, and configuring what the avatar says and does. They are written against the live API; every field, cap and error code here is the one the server actually enforces.

Environment Base URL
Production https://api.casola.ai
Staging https://api.casola-staging.net

Start here

Doc What it covers
1. Authentication Credential kinds, scopes, and which parameters each one is allowed to send
2. Choosing an avatar avatar_id, avatar_ref, avatar_version_id, persona — and the catalog routes
3. Session lifecycle Mint → connect → heartbeat → release, and the queue
4. Prompt, backstory & overrides The composition rules. Defaults vs. overrides, profiles, the additive layer
5. Configuration & tools The config options group and per-session tool wiring
6. Error reference Every error code these routes return, and what to do about it

The one rule

Everything about avatar behaviour follows a single rule, and it is worth internalizing before reading anything else:

What you edit in the dashboard becomes the avatar’s default. What you pass as an API parameter is a per-session override that never persists.

Editing a system prompt in the UI writes a new profile — a stored, versioned, hash-identified row that becomes the avatar’s default for every future session. Passing context.system_prompt on a session mint changes that one session only; nothing is stored, the next session goes back to the default, and the dashboard never shows it.

The two never fight, because they sit on different rungs of the same ladder:

per-session API parameter   ← wins, this session only
        ↓ (if absent)
stored profile              ← what the UI edits; the avatar's default
        ↓ (if absent)
sealed version baseline     ← what the avatar was created with

Resolution is per field, not per layer. Override only context.backstory and you keep the profile’s system prompt. See 4. Prompt, backstory & overrides for the full contract with worked examples.

Ten-second version

# 1. Mint a session against an avatar (server-side, secret key)
curl -sS https://api.casola.ai/api/v1/sessions \
  -H "Authorization: Bearer $CASOLA_SECRET_KEY" \
  -H "content-type: application/json" \
  -d '{"avatar_id": "019fe463-fbd3-7000-80e8-85dad81d3fee"}'
{
  "status": "ready",
  "session_id": "019fe497-ac9d-7000-804e-3bad9c970397",
  "connect_url": "https://singapore-rtx6000-1.casola.ai",
  "session_token": "eyJhbGciOiJFZERTQSIsInR5cCI6IkpXVCJ9...",
  "seat_token": "3f21c8ae-9d44-4c1e-9b7a-2e5f0d6c8a13",
  "expires_at": 1786246631,
  "cap_seconds": 300,
  "profile": { "id": "019fe463-fc2a-…", "hash_short": "a2271f20509d", "source": "default" }
}
// 2. Hand connect_url + session_token to the browser and connect
import { AvatarSession, connectViaToken } from '@casola/avatar-client';

const session = new AvatarSession({
  videoEl: document.querySelector('video#avatar')!,
  connect: connectViaToken({ connectUrl: connect_url, sessionToken: session_token }),
  workletUrl: '/mic-worklet.js',
});
await AvatarSession.ensureMicPermission();
await session.start();

The session_token is a short-lived (60 s) EdDSA JWT: it is a connect ticket, not a bearer credential. Mint it server-side, hand it straight to the browser, and let the browser connect directly to the GPU edge — no media flows through your backend.

Mental model

An avatar is two things, and they are versioned separately:

A session picks one of each — plus whatever you override for that session — and freezes the result at mint time. Editing the avatar mid-call never changes a call in flight.

Conventions used in these docs


Published at https://api-docs.casola.ai from this directory — see PUBLISHING.md.