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

ExportDescription
ExperienceSession lifecycle, speech API, events, and conversation getters
ExperienceSessionType 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.

MethodReturnsPurpose
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.