JavaScript SDK
@liforma/client — the integrator-facing JavaScript API.
Install
npm install @liforma/client Or 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_T0I7ACMQLBMPG6K'
});
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 manual listening gate (speechInputMode: 'manual') |
stopListening() | Promise<UtteranceResult> | Close gate and finalize utterance |
listenOnce(options?) | Promise<UtteranceResult> | One automatic end-of-speech capture (speechInputMode: 'auto') |
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_T0I7ACMQLBMPG6K',
mode: 'presenter',
speechInputMode: 'manual'
});
experience.on('started', async () => {
await experience.speech.speak({ text: 'Welcome to the lesson.' });
});
await experience.attach({ container: '#avatar' }); 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_T0I7ACMQLBMPG6K',
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.