Developer Reference

Perxona Widget SDK

Embed the AI avatar on your own site β€” attributes, events, and methods

Readable HTML layout Audience: Engineers embedding the widget on their own site
Blue blocks Concrete actions to take in the console.
Amber blocks Common gotchas, limits, and caveats.
Green blocks Checks that tell you things are working.
Purple blocks Prompt snippets you can hand to AI tools.

The <sv-agent> widget is a web component that drops a fully working AI avatar into any web page. This guide covers everything the integration surface offers: configuration attributes, lifecycle events, and the JavaScript methods for voice and custom rendering.

All names below are verified against the current widget build. Where the console is involved (getting your Agent Profile ID, generating embed code), see the Share dialog β†’ Embed code card described in the avatar guide.

Prerequisites

  1. API key or session token β€” one of the two is required. - The API key authenticates your widget directly. It is issued per organization; you also register the hostnames that will load the widget, and only those hosts are accepted. - A session token is a JWT you sign yourself, for teams that want to control expiry and rotation. See Session tokens below.
  2. Agent Profile ID β€” a ULID identifying which avatar and configuration to load. Copy it from the console’s embed-code screen.

Quick start

Load the SDK from the CDN, then place the component:

<script
  type="module"
  src="https://cdn.perxona.ai/prod/latest/widget/entry/index.js"
></script>

<sv-agent
  apiKey="<YOUR_API_KEY>"
  agentProfileId="<YOUR_AGENT_PROFILE_ID>"
  conversationMode="inputText"
  displayMode="fullPresentation"
></sv-agent>

Do not style sv-agent with your own CSS (position/transform/size overrides) β€” the widget manages its own layout and external CSS breaks it.

Settings can also be changed after load via JavaScript:

const widget = document.querySelector('sv-agent');
widget.updateWidgetSetting({
  presentationMode: 'bubble',
  conversationMode: 'inputText',
  cameraAngle: 'fullBody',
});

Attribute reference

Authentication and identity:

Attribute Description
apiKey Perxona API key. Keep it secret. If both apiKey and sessionToken are set, apiKey wins.
sessionToken Self-managed JWT alternative to the API key (see Session tokens).
agentProfileId ULID of the Agent Profile to load. Required.
customerRefId Optional free-form ID linking the session to your own user record β€” this is what enables cross-session memory and lets you find the visitor in the console’s Conversation history.

Layout and appearance:

Attribute Values Description
displayMode fullPresentation (default) / 3DPresentation / 2DPresentation Full widget with chat UI; 3D avatar only (you build the UI); or chat window only.
presentationMode bubble / embedded Floating chat-bubble launcher, or embedded in the page flow.
cameraAngle fullBody / halfBody Default framing of the 3D avatar.
initFov JSON, e.g. '{"distance": 1, "horizontal": 0, "vertical": 0}' Camera distance and offsets.
appearanceMode light / dark Widget color scheme.
userBubbleColor CSS color Chat-bubble accent color.
bubbleSetting JSON, e.g. '{"icon": {"src": "…"}}' Bubble launcher details such as a custom icon.
showHeader true (default) / false Whether the widget header bar is shown.

Behavior:

Attribute Values Description
readyToShowPolicy showWhenAssetsLoading (default) / showWhenAssetsReady Show immediately with a loading indicator, or only once assets finish downloading.
conversationMode inputText (default) / microphone Text input or voice interaction.
muted true / false (default) Start with audio output muted.
enableUserActivationCheck true (default) / false Wait for a real user gesture before enabling speech playback (browser autoplay rules). Set false only in controlled environments such as native WebViews that already relax autoplay β€” iOS WKWebView: mediaTypesRequiringUserActionForPlayback = []; Android WebView: setMediaPlaybackRequiresUserGesture(false).
supportedFeatures JSON, e.g. '{"multimedia": true}' Optional feature toggles; multimedia (default on) shows knowledge-base media attachments in the widget.

Events

Listen with addEventListener on the sv-agent element.

life-status β€” connection lifecycle. event.detail.status is one of disconnected, agent-preparation, downloading-assets, connection-start, connection-done, ready.

asset-download-status β€” download progress. Payload: status (always downloading-assets), asset (avatar / motion / scene), progress (0–100).

conversation-status β€” conversation lifecycle. event.detail.status is one of idle, user-inputting, user-input-done, awaiting-response, awaiting-response-done, rendering-response, timeout; input carries the user text where applicable.

agent-response-message β€” the message stream. Payload: event (user-input / agent-answer / agent-end), message, messageId (correlates a question with its answer), optional ssmlMessage, createdAt.

chat-attachment β€” fired when the multimedia display presents an attachment. Payload attachments[] with type (MIME: video/mp4, image/png, image/jpeg, application/pdf) and source (URL). Use it to e.g. pause your own page’s video while the avatar plays one.

widget.addEventListener('life-status', (e) => {
  if (e.detail.status === 'ready') console.log('avatar ready');
});

Voice control methods

Available once the widget is ready; all are methods on the element.

Method Returns Description
startRecording() Promise<boolean> Start speech recognition. Resolves false if the microphone is denied or the speech service is unavailable.
stopRecording() void Stop the current recognition session; safe to call anytime.
getRecognitionStatus() 'idle' / 'preparing' / 'recognizing' / 'unknown' Current recognition state.
isRecording() boolean Whether recognition is actively listening.
getMicrophoneVolume() number Current mic level, for volume meters. 0 when unavailable.

Custom rendering with agentReply

In 3DPresentation mode you drive the conversation UI yourself and use agentReply to render text and animation on the avatar:

widget.agentReply({ event: 'user_input', message: 'Hi!' });
widget.agentReply({ event: 'agent_answer', message: 'Hello! How can I help?', motion_id: 'greeting' });
widget.agentReply({ event: 'agent_end' });

event values: user_input (adds the question and an answer placeholder), agent_answer (renders the reply and speaks it via TTS), agent_end (closes the exchange). motion_id picks the animation: idle, talking, listening, greeting, error, or a custom motion from your storyboard.

Session token

A session token is an HS256 JWT you sign with your organization’s secret, carrying standard iat and exp claims β€” so you decide how long each embed session stays valid:

{ "iat": 1516239022, "exp": 1758004103 }

Set it via the sessionToken attribute or through updateWidgetSetting. Remove the apiKey attribute when using session tokens β€” apiKey takes priority when both are present.

Where things connect back to the console

  • The embed snippet, key management, and your Agent Profile ID live in the avatar’s Share dialog β†’ Embed code card.
  • Media attachments shown by the multimedia display are configured in the Knowledge base.
  • Conversations from embedded widgets β€” including customerRefId β€” appear under Conversation history.