Add a MeshLite avatar to your site
The avatar runs in an iframe served by MeshLite and is rendered in your visitor’s browser. Your page loads one script, your server issues short-lived session tokens, and voice and AI come from your own provider account.
No code to write? Use “Put on my site”
In the Console, open Put on my site, enter your site’s address and choose an avatar. You get a code to paste once before </body>, or an instruction for your AI agent (ChatGPT, Claude, Cursor, Lovable, Bolt). The code has no secret key and needs no server or API key. It works only on your site, with its www address. The Console shows where to paste it in WordPress, Shopify, Wix, Webflow and Squarespace. The project changes to Live when a page of your site shows the avatar. Add or remove avatars later without changing the code.
The rest of this page is the developer integration: your own server, your own buttons and full control of the session.
Using an AI coding agent?
Paste this prompt into Claude Code, Codex, Cursor or another coding agent. It follows our integration guide for agents, writes the server route and the page code, and tells you what to set up in the Console. Your secret key stays out of the chat: you add it to your .env file yourself.
Add a MeshLite talking avatar to this website. Follow the guide at https://meshlite.io/llms.txt (if you can't open it, ask me to paste it). Ask me for my MeshLite publishable key and, optionally, an avatar ID. Never ask me to paste my secret key: put a placeholder in .env and I'll add it myself. If I don't have a MeshLite account, send me to https://console.meshlite.io/console?plan=free#signup first.Agent without web access? Copy the full guide and paste it into the conversation.
Create your workspace
Sign up in the Console: free, no card, activated from the email we send. The Free plan can go live on one site (a domain with its www address and subdomains), with the default avatars, the MeshLite watermark on the avatar and up to 3 simultaneous conversations; the avatar speaks through your own voice provider. Removing the watermark needs a paid plan.
Set up the Console
The developer settings are under Put on my site, in the tabs marked “advanced”.
- Domains (advanced): add every origin that will show the avatar, exactly as the browser sees it, port included:
http://localhost:3000for local development,https://for anything else. - API keys (advanced): create a publishable key and a secret key in the same environment. Test keys (
ml_pk_test_…) work with test domains; live keys with live domains. On a public page, a test key shows a MeshLite label on the avatar. - TTS & LLM: connect your voice provider with your own key: OpenAI, Azure OpenAI Realtime, Azure AI Speech or ElevenLabs. Every account also gets 5 minutes of MeshLite voice a day, shared by your site and the Console, to help while you set up; after that, the avatar speaks through your provider.
- Personalities: write what the avatar knows and how it speaks, publish it and assign it to your avatar and website.
- Code per avatar (advanced): copy your avatar ID. This tab also shows the code below with your own values filled in.
Then add them to your server’s environment. The secret key never goes in browser code or Git.
MESHLITE_SECRET_KEY=ml_sk_test_...
MESHLITE_PUBLISHABLE_KEY=ml_pk_test_...
MESHLITE_ORIGIN=http://localhost:3000
MESHLITE_AVATAR=Issue session tokens from your server
Your server keeps the secret key and asks MeshLite for a session token. Call this from a POST /api/meshlite-session route and return { sessionToken }. Tokens last 2 minutes; the SDK asks for a new one when it needs it. Node.js 18+, no dependency:
export async function createMeshLiteSession() {
const response = await fetch("https://console.meshlite.io/api/v1/client-sessions", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.MESHLITE_SECRET_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
publishableKey: process.env.MESHLITE_PUBLISHABLE_KEY,
origin: process.env.MESHLITE_ORIGIN, // from your config, never from the request
avatar: process.env.MESHLITE_AVATAR || undefined,
conversation: { language: "en", responseStyle: "concise", idleTimeout: 30 },
}),
});
const body = await response.json();
if (!response.ok) throw new Error(`MeshLite ${body.error?.code}: ${body.error?.message}`);
return body.sessionToken;
}The route is public: rate-limit it, or put it behind your own sign-in if only signed-in users should talk to the avatar.
Mount the avatar in your page
The iframe takes the size of its container. Browsers only open the microphone after a click, so start the conversation from one.
<div id="avatar" style="width:340px;height:510px"></div>
<button id="talk">Talk to the avatar</button>
<script src="https://console.meshlite.io/sdk/1.11.46/meshlite.js" crossorigin="anonymous"></script>
<script>
const avatar = MeshLite.mount({
container: "#avatar",
avatar: "YOUR_AVATAR_ID", // same as MESHLITE_AVATAR; remove for the default avatar
locale: "en",
publishableKey: "ml_pk_test_...", // safe to expose
sessionToken: async () => {
const response = await fetch("/api/meshlite-session", { method: "POST" });
if (!response.ok) throw new Error("Could not start the avatar session");
return (await response.json()).sessionToken;
},
conversation: { language: "en", responseStyle: "concise", idleTimeout: 30 },
captions: "overlay",
});
avatar.on("error", (message, detail) => console.error("MeshLite", detail.code, message));
document.getElementById("talk").addEventListener("click", () => avatar.startConversation());
</script>React, Next.js, Vue: load the script once, mount in a client-side effect (useEffect, onMounted) and call avatar.unmount() in its cleanup. There is no npm package: load the SDK from console.meshlite.io only.
Going live
Under Domains (advanced), add your production domain as a live domain (HTTPS), create live keys and replace the test values in your environment. No code change is needed. The Free plan goes live on one site with the MeshLite watermark; paid plans add custom avatars, and from Creator up they also remove the watermark and allow more simultaneous conversations (Lite keeps a MeshLite attribution).
Reference
- Versions: the current SDK is 1.11.46. Pin an exact version; the Console’s “Code per avatar” tab always shows the current one. Only recent versions are served. Older version URLs redirect to the current one, so update the pinned version when a new one is released.
- Types:
https://console.meshlite.io/sdk/1.11.46/meshlite.d.ts - Content Security Policy: if your site has one, allow
https://console.meshlite.ioinscript-srcandframe-src, and also inconnect-srcfor the “Put on my site” code. If you send a Permissions-Policy header, allow the microphone for that origin too. - LiveKit agents: the avatar can lip-sync the voice of your own LiveKit agent, which keeps its own brain and voice. Setup is assisted for now: write to us to get started.
- Browsers: HTTPS is required in production. Older browsers that can’t run the avatar show an idle preview only; check
MeshLite.supportsConversation(). - Common errors:
ORIGIN_NOT_ALLOWEDmeans the page’s origin (port included) is not registered in the keys’ environment;ENVIRONMENT_MISMATCHmeans a test key is paired with a live key;VOICE_PROVIDER_REQUIREDmeans no voice provider is connected. The full guide lists every option, event and error.
Questions about your integration? Write to hello@meshlite.io.