JavaScript SDK
Install
npm install @liforma/clientOr load from CDN (v2 speak API):
<script src="https://cdn.liforma.ai/sdk/v2/client.js"><\/script>Primary API
import { Experience } from '@liforma/client';
const experience = await Experience.startSession({
experienceId: 'exp_t0i7acmq'
});
await experience.attach({ container: '#avatar' });Marketing attribution is captured automatically from the embedding page’s UTM query parameters
and referrer. Pass an attribution object to override the whole snapshot, or
attribution: false to send none. REST mint is explicit-only.
If the visitor is already registered (or already converted for another milestone), pass
alreadyConverted: [‘registration’] at mint so conversion rate uses an eligible
denominator. Then record new registrations with experience.conversion(‘registration’)
or POST /v1/sessions/{id}/conversions. Unique per session+key.
Exports
| Export | Description |
|---|---|
Experience | Session lifecycle, speech API, events, and conversation getters |
ExperienceSession | Type alias for the live session returned by Experience.startSession() |
The Svelte component is also named Experience — import it from
@liforma/client/svelte. See Svelte Component.
Lifecycle
await experience.attach({ container });
experience.pause();
experience.resume();
await experience.end();attach() mounts the player iframe. ready fires when visuals are mounted;
started fires after the player start button unlocks audio — required before speech
APIs. See Events.
Speech API
Presenter sessions, manual listening, automatic capture, and custom processors. Requires
attach() and the started event. Full reference:
Experience API.
| Method | Returns | Purpose |
|---|---|---|
speak(options) | Promise<SpeechResult> | Animated character speech (text, optional characterId, behavior) |
startListening() | Promise<void> | Open the listening gate. The session must be manual, which a host sets with microphoneActivation: ‘tap_to_talk’ or ‘push_to_talk’. |
stopListening() | Promise<UtteranceResult> | Close gate and finalize utterance |
listenOnce(options?) | Promise<UtteranceResult> | One automatic end-of-speech capture (speechInputMode: ‘auto’) |
submitUserMessage({ text }) | Promise<void> | Submit a host-typed user turn. Resolves when the player queues it. Requires allowTextInput. |
toggleSettings() | void | Toggle the player settings panel (microphone, speakers, listening mode, language). |
getConversation() | readonly ConversationMessage[] | Flat ordered session history snapshot |
getLastTurn() | readonly ConversationMessage[] | Messages in the latest turn |
focusCharacter(characterId) | Promise<void> | Presentation-only focus on a multi-Character node; no-op on single-Character nodes |
Session options
Pass conversationProcessor and onUserTranscript on
Experience.startSession(). See
Custom Conversation Processor.
Presenter + manual listening
const experience = await Experience.startSession({
experienceId: 'exp_t0i7acmq',
mode: 'presenter'
});
experience.on('started', async () => {
await experience.speech.speak({ text: 'Welcome to the lesson.' });
});
await experience.attach({
container: '#avatar',
microphoneActivation: 'tap_to_talk'
});speak()
const result = await experience.speech.speak({
text: 'Repeat after me: Buenos días.',
characterId: 'char_…', // optional — defaults to activeCharacterId
queue: 'append' // optional — append (default), replace-active, or replace-all
});
console.log(result.utteranceId, result.durationMs, result.status);Manual listening
await experience.startListening();
// Learner speaks; pauses do not end the utterance in manual mode.
const utterance = await experience.stopListening();
console.log(utterance.utteranceId, utterance.text);listenOnce()
const experience = await Experience.startSession({
experienceId: 'exp_t0i7acmq',
mode: 'presenter',
speechInputMode: 'auto'
});
experience.on('started', async () => {
await experience.speech.speak({ text: 'What is your party size?' });
const answer = await experience.listenOnce({ timeoutMs: 15_000 });
console.log(answer.utteranceId, answer.text);
});
await experience.attach({ container: '#avatar' });Conversation getters
const history = experience.getConversation();
const lastTurn = experience.getLastTurn();
experience.on('conversationUpdate', (evt) => {
console.log('History length', evt.data.length);
});Events
Register handlers with experience.on(event, handler). Speech-related events include
ready, started, userTranscript,
userSpeechStarted, userSpeechEnded,
characterSpeechStarted, characterSpeechEnded,
characterFocusChanged,
conversationUpdate, conversationProcessorError, and
listeningState. See the full list on
Events.
Patterns: Guided Scripted Practice, Listen Once Capture, Custom Conversation Processor.