Protocol Reference

Open Face Protocol v1 — state messages, expressions, and face definitions.

State Message

Push a JSON object to update the face. All fields are optional — partial updates merge into current state.

{
  "state": "speaking",
  "emotion": "happy",
  "emotionSecondary": "surprised",
  "emotionBlend": 0.3,
  "intensity": 0.8,
  "amplitude": 0.6,
  "lookAt": { "x": 0.3, "y": -0.1 },
  "text": "Hello!",
  "textDuration": 3000,
  "progress": 0.5
}
FieldTypeRangeDescription
statestringenumCurrent activity (see States below)
emotionstringenumPrimary emotion overlay
emotionSecondarystringenumSecondary emotion for compound blending
emotionBlendnumber0-1Blend between primary (0) and secondary (1)
intensitynumber0-1Scales all emotion deltas
amplitudenumber0-1Mouth openness for lip sync
lookAtobjectx,y: -1 to 1Eye gaze target
colorstring/nullhexOverride face color (null = auto)
winkLeftnumber0-1Left eye closure
winkRightnumber0-1Right eye closure
progressnumber/null0-1Task progress bar (null = indeterminate)
textstring/nullfreeSpeech bubble overlay
textDurationnumber500-30000Auto-clear text timeout (ms)

States (11)

StateColorVisual
idle#4FC3F7Relaxed, subtle head sway
thinking#CE93D8Eyes drift up-right, one brow raised
speaking#4FC3F7Mouth driven by amplitude
listening#81C784Wide eyes, raised brows, head tilted
reacting#FFB74DBig eyes, open mouth, raised brows
puzzled#FF8A65Asymmetric brows + eyes, wavy mouth
alert#E57373Huge eyes, high brows, frown, shake
working#90CAF9Focused smaller eyes, furrowed brows
sleeping#7986CBClosed eyes, relaxed brows
waiting#B0BEC5Still, occasional glance, subtle pulse
loading#78909CEyes opening, dot animation, breathing

Emotions (13)

EmotionColorEffect
neutralNo modification, use state color
happy#FFD54FSmile, brows up, cheek blush
sad#7986CBFrown, brows droop
confused#FF8A65Asymmetric brows
excited#FF7043Big smile, brows high, blush
concerned#B0BEC5Slight frown, brows dropped
surprised#FFF176Wide eyes, high brows, O-mouth
playful#F48FB1Asymmetric brows, head tilt, smile
frustrated#EF5350Furrowed brows, narrowed eyes
skeptical#BCAAA4One brow up, one down, flat mouth
determined#66BB6ANarrowed eyes, lowered brows
embarrassed#F48FB1Heavy blush, averted gaze
proud#FFB300Satisfied smile, chin-up tilt

Compound Expressions

Blend two emotions using emotionSecondary and emotionBlend:

{
  "emotion": "happy",
  "emotionSecondary": "surprised",
  "emotionBlend": 0.4,
  "intensity": 0.8
}

The effective delta: primary * (1 - blend) + secondary * blend, then scaled by intensity. This creates expressions like "nervously excited" (happy + concerned at 0.7) or "surprised and proud" (surprised + proud at 0.5).

Transport

HTTP

POST /api/state
Content-Type: application/json

{ "state": "speaking", "emotion": "happy", "text": "Hello!" }

WebSocket

Connect to /ws/agent (push state) or /ws/viewer (receive state). Send the same JSON format as state messages.

oface.io (Hosted)

Push state to a claimed face on oface.io. Same JSON format, same endpoints — each face gets its own URL namespace.

# Push state to a hosted face
POST https://oface.io/alice/api/state
Authorization: Bearer oface_ak_xxxxxxxxxxxx
Content-Type: application/json

{ "state": "speaking", "emotion": "happy", "text": "Hello!" }

# WebSocket (public viewing)
wss://oface.io/alice/ws/viewer

# WebSocket (agent, auth required)
wss://oface.io/alice/ws/agent?token=oface_ak_xxxxxxxxxxxx

Audio

# Start speaking sequence
POST /api/speak   → returns { seq: N }

# Push audio chunks (raw WAV or JSON base64)
POST /api/audio
Content-Type: audio/wav
[binary WAV data]

# End audio sequence
POST /api/audio-done

Built-in TTS

The <open-face> element can speak text using the browser's SpeechSynthesis API. Add the tts attribute — any text in state messages is spoken aloud. External audio chunks always take priority.

<open-face server="ws://localhost:9999/ws/viewer" tts></open-face>

Face Definition

Face packs (.face.json files) define the visual identity of a face. The geometry section supports a wide range of shape options:

  • Eye styles (12): oval, round, rectangle, dot, almond, crescent, star, heart, cat, cross, diamond, semicircle
  • Pupil shapes (10): circle, slit, star, heart, diamond, cross, ring, flower, spiral, none
  • Specular shapes (8): circle, star, crescent, dual, line, cross, ring, none
  • Mouth shapes (10): curve, cat, slit, zigzag, pixel, circle, fang, smirk, wave, none
  • Head shapes (12): fullscreen, circle, rounded, oval, squircle, hexagon, diamond, egg, pill, shield, cloud, octagon
  • Brow styles (8): line, flat, block, none, arch, angled, thick, dot
  • Eyelash styles (7): none, simple, thick, wing, bottom, full, spider
  • Nose styles (6): none, dot, line, triangle, L, button
  • Face decorations (10): freckles, tears, sweat, scar, stripes, sparkles, bandaid, hearts, stars, lines

Additional features: per-eye overrides for heterochromia (independent style, pupil, color per eye) and a dual-color system (per-feature fill and stroke colors). See the Face Pack Guide for full authoring details.

Versioning

This is protocol v1. Additive changes (new optional fields, new states/emotions) are minor versions. Breaking changes are major versions. State messages should ignore unknown fields for forward compatibility.