<iframe> on any website. The avatar then connects directly from your visitor’s browser to the agent — no backend required on your side.
Prerequisites
Enable embedding
Open the agent in the dashboard and turn on Allow embedding. Only shared agents can be embedded. Toggling this switch is saved immediately — you can test right away without saving the agent manually first.
Allow your origin
Under Allowed origins, add the address(es) of the page(s) that may run the avatar — for example
https://www.your-domain.com.Quickstart
AGENT_ID with your agent’s UUID (visible in the dashboard).
The
allow="microphone; autoplay" attribute is required: without microphone the visitor cannot speak, and without autoplay audio playback will not start automatically in some browsers (the “Enable sound” overlay takes over instead).Fullscreen displays
Embedding always renders the avatar inline, inside the iframe container you place on your page. For a standalone, fullscreen display — for example an unattended kiosk stand — use the dedicated Kiosk mode instead of an iframe. It opens directly as a top-level page (no iframe) and adds a screen wake lock, an idle auto-reset, and a home-screen web app for true fullscreen.Query parameters
All options are appended as query parameters to the/embed URL. Invalid values fall back to their defaults automatically.
Background / letterbox color as a 6-digit hex value without
# (e.g. f5f5f5).UI language of the controls.
de or en.With
true the text-chat input is hidden (voice/avatar-only mode).With
true the “Hang up” button is shown.The microphone stays open for the duration of a conversation. If you want to mute or re-enable it from your page (e.g. your own push-to-talk button), control it via
postMessage — see Messaging.Example with multiple options
Messaging
Beyond simply embedding the avatar, you can control it programmatically and react to its behavior. An embedded agent runs inside an<iframe>, so your page and the avatar live in different browser contexts. They communicate through the standardized window.postMessage API: you send messages to the iframe and receive events from it.
Every message carries the avaluma: prefix so that foreign messages (e.g. from third-party scripts) are safely ignored.
Get a reference to the iframe
Give your embed anid so you can address its contentWindow:
Flow (handshake)
The bridge announces itself with aready beacon on every (re)mount. The parent page confirms with init, registering its origin as the target for outbound events.
Send init back
The parent page replies with
{ type: "avaluma:init" }. Only then does the bridge know the target origin and can deliver events.Send messages to the avatar
Send a message to the iframe’scontentWindow. Always pass the Avaluma origin as the second argument so the message is only delivered to the avatar:
| Message | Payload | Effect |
|---|---|---|
avaluma:init | — | Registers the parent page’s origin and completes the handshake. Send on every ready beacon. |
avaluma:sendMessage | { text } | Sends text to the agent — as if the user had typed it into the chat field. Empty messages are ignored. |
avaluma:setMicrophone | { enabled } | Turns the visitor’s microphone on (true) or mutes it (false). Use this to build your own push-to-talk button on your page, for example. |
A conversation is started by the visitor via “Start conversation” inside the iframe.
avaluma:sendMessage only takes effect while a conversation is active.Receive events from the avatar
Listen formessage events on window. Always check event.origin before trusting the data:
| Event | Data | Meaning |
|---|---|---|
avaluma:ready | — | The bridge is ready. Sent on every (re)mount — respond with init. |
avaluma:connected | — | A conversation has been established (avatar connected). |
avaluma:disconnected | — | The conversation has ended. |
avaluma:agentMessage | { id, text, final } | A message from the agent. Transcripts are streamed — the same id is sent multiple times with growing text. |
How is "final" determined?
How is "final" determined?
Typed chat messages are immediately
final: true. Streamed speech transcripts are considered complete once the text stops changing for about 1 second — then exactly one closing final: true event with the full text follows. Multiple events with the same id belong to the same message; use the id to update the display instead of appending. If you only need the final result, filter for final === true.Full test example
A standalone HTML page that embeds the avatar, sends text to it, and shows all events in a small log. Serve it locally with a static server (e.g.python3 -m http.server 8080) and add its origin (http://localhost:8080) to the agent’s Allowed origins.
Security checklist
Always specify the target origin
Never use
"*" as the target origin in postMessage. Pass https://avaluma.ai so messages can’t reach other frames.Always verify the source origin
In your
message listener, reject every event whose event.origin is not https://avaluma.ai.